Android网络请求框架----Okhttp3完全解析(2),封装框架

前言:

其实okhttp3更多的我也是先看别人的博客和官方的文档信息后才开始用,而且网上关于这样流行的框架的知识也是不胜枚举,关于该框架的封装主要还是看了慕课网上视频链接相关的视频,然后在他封装的基础上进行改进的,其实okhttp已经非常好用和简洁了,但是还是有些参数需要进行配置,并且这个封装代码量也不是很多,比较好容易进行理解,同时更推荐大家直接将代码copy到项目中,然后根据自己的需求进行一个动态的修改,这样的封装就很DIY了。

类的说明:

Android网络请求框架----Okhttp3完全解析(2),封装框架_第1张图片
相关的类大概也就这些。下面来一个一个进行讲解。
1.首先来看最重要的配置类:CommonOkHttpClient
代码:

public class CommonOkHttpClient
{
    private static final int TIME_OUT = 30;
    private static OkHttpClient mOkHttpClient;
    // private static CommonOkHttpClient mClient = null;

    //静态代码块吃初始化Client相关的信息
    static
    {
        OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder();
        okHttpClientBuilder.hostnameVerifier(new HostnameVerifier()
        {
            @Override
            public boolean verify(String hostname, SSLSession session)
            {
                return true;
            }
        });

        okHttpClientBuilder.cookieJar(new SimpleCookieJar());
        okHttpClientBuilder.connectTimeout(TIME_OUT, TimeUnit.SECONDS);
        okHttpClientBuilder.readTimeout(TIME_OUT, TimeUnit.SECONDS);
        okHttpClientBuilder.writeTimeout(TIME_OUT, TimeUnit.SECONDS);
        okHttpClientBuilder.followRedirects(true);
        /**
         * trust all the https point
         */
        okHttpClientBuilder.sslSocketFactory(HttpsUtils.getSslSocketFactory());
        mOkHttpClient = okHttpClientBuilder.build();
    }

    /**
     * 指定cilent信任指定证书
     * 
     * @param certificates
     */
    public static void setCertificates(InputStream... certificates)
    {
        mOkHttpClient.newBuilder().sslSocketFactory(HttpsUtils.getSslSocketFactory(certificates, null, null)).build();
    }

    /**
     * 指定client信任所有证书
     */
    public static void setCertificates()
    {
        mOkHttpClient.newBuilder().sslSocketFactory(HttpsUtils.getSslSocketFactory());
    }

    /**
     * 通过构造好的Request,Callback去发送请求
     * 
     * @param request
     * @param callback
     */
    public static Call get(Request request, DisposeDataHandle handle)
    {
        Call call = mOkHttpClient.newCall(request);
        call.enqueue(new CommonJsonCallback(handle));
        return call;
    }

    public static Call post(Request request, DisposeDataHandle handle)
    {
        Call call = mOkHttpClient.newCall(request);
        call.enqueue(new CommonJsonCallback(handle));
        return call;
    }

    public static Call downloadFile(Request request, DisposeDataHandle handle)
    {
        Call call = mOkHttpClient.newCall(request);
        call.enqueue(new CommonFileCallback(handle));
        return call;
    }
}

静态代码块初始化保证了OkHttpClient的全局对象的唯一和相关参数的配置。
静态的get,post和文件下载的方法可以保证基本的网络请求需要,如果你的项目中有其他的需求,也可以在这里添加方法。

2.静态方法需要的Request来自于request包下的CommonRequest和RequestParam类
先看:RequestParam

public class RequestParams {

    public ConcurrentHashMap urlParams = new ConcurrentHashMap();
    public ConcurrentHashMap fileParams = new ConcurrentHashMap();

    /**
     * Constructs a new empty {@code RequestParams} instance.
     */
    public RequestParams() {
        this((Map) null);
    }

    /**
     * Constructs a new RequestParams instance containing the key/value string
     * params from the specified map.
     *
     * @param source
     *            the source key/value string map to add.
     */
    public RequestParams(Map source) {
        if (source != null) {
            for (Map.Entry entry : source.entrySet()) {
                put(entry.getKey(), entry.getValue());
            }
        }
    }

    /**
     * Constructs a new RequestParams instance and populate it with a single
     * initial key/value string param.
     *
     * @param key
     *            the key name for the intial param.
     * @param value
     *            the value string for the initial param.
     */
    public RequestParams(final String key, final String value) {
        this(new HashMap() {
            {
                put(key, value);
            }
        });
    }

    /**
     * Adds a key/value string pair to the request.
     *
     * @param key
     *            the key name for the new param.
     * @param value
     *            the value string for the new param.
     */
    public void put(String key, String value) {
        if (key != null && value != null) {
            urlParams.put(key, value);
        }
    }

    public void put(String key, Object object) throws FileNotFoundException {

        if (key != null) {
            fileParams.put(key, object);
        }
    }
}

无非就是将String对象和Object对象(上传File时)的key-value键值对放进map对象中,
再看看CommonRequest类:

public class CommonRequest {

    /**
     * create the josn Request
     *
     * @param url
     * @param json
     * @return
     */
    public static Request createPostJsonRequest(String url, String json) {
        RequestBody requestbody = RequestBody.create(MediaType.parse("application/json"), json);
        return new Request.Builder().url(url).post(requestbody).build();
    }

    /**
     * create the key-value Request
     * 
     * @param url
     * @param params
     * @return
     */
    public static Request createPostRequest(String url, RequestParams params) {
        FormBody.Builder mFormBodyBuild = new FormBody.Builder();
        if (params != null) {
            for (Map.Entry entry : params.urlParams.entrySet()) {
                mFormBodyBuild.add(entry.getKey(), entry.getValue());
            }
        }
        FormBody mFormBody = mFormBodyBuild.build();
        return new Request.Builder().url(url).post(mFormBody).build();
    }

    /**
     * ressemble the params to the url
     * 
     * @param url
     * @param params
     * @return
     */
    public static Request createGetRequest(String url, RequestParams params) {
        StringBuilder urlBuilder = new StringBuilder(url).append("?");
        if (params != null) {
            for (Map.Entry entry : params.urlParams.entrySet()) {
                urlBuilder.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
            }
        }
        return new Request.Builder().url(urlBuilder.substring(0, urlBuilder.length() - 1)).get().build();
    }

    /**
     * 文件上传请求
     * 
     * @return
     */
    private static final MediaType FILE_TYPE = MediaType.parse("application/octet-stream");

    public static Request createMultiPostRequest(String url, RequestParams params) {

        MultipartBody.Builder requestBody = new MultipartBody.Builder();
        requestBody.setType(MultipartBody.FORM);
        if (params != null) {

            for (Map.Entry entry : params.fileParams.entrySet()) {
                if (entry.getValue() instanceof File) {
                    requestBody.addPart(Headers.of("Content-Disposition", "form-data; name=\"" + entry.getKey() + "\""),
                            RequestBody.create(FILE_TYPE, (File) entry.getValue()));
                } else if (entry.getValue() instanceof String) {

                    requestBody.addPart(Headers.of("Content-Disposition", "form-data; name=\"" + entry.getKey() + "\""),
                            RequestBody.create(null, (String) entry.getValue()));
                }
            }
        }
        return new Request.Builder().url(url).post(requestBody.build()).build();
    }
}

这个类就是对request请求参数进行一个简单的封装,CommonOkHttpClient里面调用的request对象就是从这面蛇生成的。同时,我们还需要一个回调接口来监听成功和失败。
3 成功的时候我们需要对数据进行解析,所以在Response包中,有两个类,一个是处理File对象,一个是处理Json对象,我们看返回为json数据时类:

public class CommonJsonCallback implements Callback {

    /**
     * the logic layer exception, may alter in different app
     */
    protected final String RESULT_CODE = "ecode"; // 有返回则对于http请求来说是成功的,但还有可能是业务逻辑上的错误
    protected final int RESULT_CODE_VALUE = 0;
    protected final String ERROR_MSG = "emsg";
    protected final String EMPTY_MSG = "";
    protected final String COOKIE_STORE = "Set-Cookie"; // decide the server it
    // can has the value of
    // set-cookie2

    /**
     * the java layer exception, do not same to the logic error
     */
    protected final int NETWORK_ERROR = -1; // the network relative error
    protected final int JSON_ERROR = -2; // the JSON relative error
    protected final int OTHER_ERROR = -3; // the unknow error

    /**
     * 将其它线程的数据转发到UI线程
     */
    private Handler mDeliveryHandler;
    private DisposeDataListener mListener;
    private Class mClass;

    public CommonJsonCallback(DisposeDataHandle handle) {
        this.mListener = handle.mListener;
        this.mClass = handle.mClass;
        this.mDeliveryHandler = new Handler(Looper.getMainLooper());
    }

    @Override
    public void onFailure(final Call call, final IOException ioexception) {
        /**
         * 此时还在非UI线程,因此要转发
         */
        mDeliveryHandler.post(new Runnable() {
            @Override
            public void run() {
                mListener.onFailure(new OkHttpException(NETWORK_ERROR, ioexception));

            }
        });
    }

    @Override
    public void onResponse(final Call call, final Response response) throws IOException {
        final String result = response.body().string();

        final ArrayList cookieLists = handleCookie(response.headers());
        mDeliveryHandler.post(new Runnable() {
            @Override
            public void run() {
                handleResponse(result);
                /**
                 * handle the cookie
                 */
                if (mListener instanceof DisposeHandleCookieListener) {
                    ((DisposeHandleCookieListener) mListener).onCookie(cookieLists);
                }
            }
        });
    }

    private ArrayList handleCookie(Headers headers) {
        ArrayList tempList = new ArrayList();
        for (int i = 0; i < headers.size(); i++) {
            if (headers.name(i).equalsIgnoreCase(COOKIE_STORE)) {
                tempList.add(headers.value(i));
            }
        }
        return tempList;
    }

    private void handleResponse(String responseObj) {
        if (null == responseObj) {
            mListener.onFailure(new OkHttpException(NETWORK_ERROR, EMPTY_MSG));

            return;
        }
        try {
            if (mClass == null) {
                mListener.onSuccess(responseObj);
            } else {

                Object obj = JSON.parseObject(responseObj.toString(), mClass);
                if (obj != null) {
                    mListener.onSuccess(obj);
                } else {
                    mListener.onFailure(new OkHttpException(JSON_ERROR, EMPTY_MSG));

                }
            }

        } catch (Exception e) {
            mListener.onFailure(new OkHttpException(OTHER_ERROR, e.getMessage()));

            e.printStackTrace();
        }
    }
}

这个类要结合其他的类来看更好理解些,等下可以下载源码来看,但是这个类理解起来也是比较简单的。首先定义的对象的状态码需要改成你们自己服务器定义的。成功和失败时因为在子线程中,所以需要handle进行通信。同时针对cookie也做了单独的处理。fastjson进行解析。

使用:

    private void httpGetF() {
        String url="";
        CommonOkHttpClient.get(CommonRequest.createGetRequest(url,null),new DisposeDataHandle(new DisposeDataListener() {
            @Override
            public void onSuccess(User responseObj) {}
            @Override
            public void onFailure(User reasonObj) {}
        }));
    }


    private void httpPostF() {
        String url="";
        RequestParams requestParams=new RequestParams();
        requestParams.put("key1","param1");
        requestParams.put("key2","param2");
        CommonOkHttpClient.post(CommonRequest.createPostRequest(url,requestParams),new DisposeDataHandle(new DisposeDataListener() {
            @Override
            public void onSuccess(User responseObj) {}
            @Override
            public void onFailure(User reasonObj) {}
        }));
    }

还是比较简单的哈

欢迎下载

你可能感兴趣的:(github框架)