超简单的okhttp封装工具类(上)

来源:互联网 发布:2016年十大网络神曲 编辑:程序博客网 时间:2024/05/18 16:18

前言:

提及访问网络,很自然的会用到okHttp,虽然okhttp已经封装的比较完善,调用也比较方便,但对于向我这样比较懒的人,okhttp的调用还是略显复杂,每次都要写同样重复的代码,简直不能忍受,那就封装以下一句话调用完毕,岂不快哉。。。废话不多说,请抓稳扶好,老司机,走起。。。

重要的事情提一提:看不懂的文章最后有完整代码,看看完整版应该就没问题了。

okHttp使用流程

没有什么是一张图说不清的,走起

这里写图片描述

高逼格的封装开始

网络访问框架一般都需要单例模式(singleton),首先我们也进行单利模式。1 首先私有化构造器,让别人不能new出其它实例。2 声明该类的一个静态成员变量实例,本篇为instance3 声明一个公有的方法getInstance提供给调用者本类实例。 /** * 网络访问要求singleton */private static OkHttpUtils instance;// 必须要用的okhttpclient实例,在构造器中实例化保证单一实例private OkHttpClient mOkHttpClient;private OkHttpUtils() {    /**     * okHttp3中超时方法移植到Builder中     */    mOkHttpClient = (new OkHttpClient()).newBuilder()                .connectTimeout(10, TimeUnit.SECONDS)                .readTimeout(10, TimeUnit.SECONDS)                .writeTimeout(30, TimeUnit.SECONDS)                .build();}public static OkHttpUtils getInstance() {    if (instance == null) {        synchronized (OkHttpUtils.class) {            if (instance == null) {                instance = new OkHttpUtils();            }        }    }    return instance;}上面代码在构造器中实例化出了okHttpClient的实例,既然我们这个帮助类是单例的,那么构造器中的okHttpClient也只会走一次,必定也是单实例的。

提供GET和POST两种访问方式的方法

既然是工具类,肯定要更加简单,此处我们需要提供针对GET和POST两种方式的访问方法。

1.工具类为GET访问方式提供的方法

 /** * 对外提供的Get方法访问 * @param url * @param callBack */public void Get(String url, MyCallBack callBack) {    /**     * 通过url和GET方式构建Request     */    Request request = bulidRequestForGet(url);    /**     * 请求网络的逻辑     */    requestNetWork(request, callBack);}

2.工具类为POST访问方式提供的方法(表单数据)

/** * 对外提供的Post方法访问 * @param url * @param parms: 提交内容为表单数据 * @param callBack */public void PostWithFormData(String url, Map<String, String> parms, MyCallBack callBack) {    /**     * 通过url和POST方式构建Request     */    Request request = bulidRequestForPostByForm(url, parms);    /**     * 请求网络的逻辑     */    requestNetWork(request, callBack);}

3.工具类为POST访问提供方法(JSON数据)

 /** * 对外提供的Post方法访问 * @param url * @param json: 提交内容为json数据 * @param callBack */public void PostWithJson(String url, String json, MyCallBack callBack) {    /**     * 通过url和POST方式构建Request     */    Request request = bulidRequestForPostByJson(url, json);    /**     * 请求网络的逻辑     */    requestNetWork(request, callBack);}

从这两个方法,我们能看到我们需要构建GET和POST访问方式对应的Request对象和我们自定义的MycallBack接口,下面先来看一下构建Request对象。

构建Request对象

为了大家更好的理解封装流程,首先请大家回顾一下okhttp的使用流程:mOkHttpClient.newCall(request).enqueue(new Callback() {})

1.首先我们来看构建GET需要的Request对象,这个也是最简单的。

  /** * GET方式构建Request * @param url * @return */private Request bulidRequestForGet(String url) {    return new Request.Builder()            .url(url)            .get()            .build();}

2.构建提交表单数据的Request对象

/** * POST方式构建Request {Form} * @param url * @param parms * @return */private Request bulidRequestForPostByForm(String url, Map<String, String> parms) {    FormBody.Builder builder = new FormBody.Builder();    if (parms != null) {        for (Map.Entry<String, String> entry :                parms.entrySet()) {            builder.add(entry.getKey(), entry.getValue());        }    }    FormBody body = builder.build();    return new Request.Builder()            .url(url)            .post(body)            .build();}

3.构建提交json数据的Request对象

 /** * POST方式构建Request {json} * @param url * @param json * @return */private Request bulidRequestForPostByJson(String url, String json) {    RequestBody body = RequestBody.create(JSON, json);    return new Request.Builder()            .url(url)            .post(body)            .build();}

开始处理联网逻辑

上述代码及分析基本上把简单封装的东西讲完了,有了okhttpclient和request对象我们需要处理联网逻辑了,也就是上述的 requestNetWork方法。 private void requestNetWork(Request request, MyCallBack callBack) {    /**     * 处理连网逻辑,此处只处理异步操作enqueue     */    callBack.onLoadingBefore(request);    mOkHttpClient.newCall(request).enqueue(new Callback() {        @Override        public void onFailure(Call call, IOException e) {            callBack.onFailure(request, e);        }        @Override        public void onResponse(Call call, Response response) throws IOException {            if (response.isSuccessful()) {                callBack.onSuccess(response);            } else {                callBack.onError(response);            }        }    });}

MyCallBack对象分析

看到此处,估计有人会一脸懵逼,这个MyCallBack是个什么鬼。其实这是我定义的一个接口,那么为什么要定义她呢。因为我们在使用我们的工具类的时候,访问网络成功后肯定会有数据返回,我们怎么处理呢,okhttp内部通过一个callBack把数据回调回来,那么我们自己封装的工具类不妨仿照他的做法  定义一个接口回调Response的内容。贴一下接口的内容interface MyCallBack {void onLoadingBefore(Request request);void onSuccess(Response response);void onFailure(Request request, Exception e);void onError(Response response);

}

封装进阶

看到此处,觉得封装已经完结了,不不不,还有一个重要的问题,不处理的话会导致崩溃的,这个问题就是,我们定义接口回调的地方是在子线程,而我们的Response很明显需要拿回到主线程进行UI的更新,所以访问网络的方法requestNetWork需要通过Handler把子线程的Resonse发送到主线程,请看详细实现。
private void requestNetWork(Request request, MyCallBack callBack) {

    /**     * 处理连网逻辑,此处只处理异步操作enqueue     */    callBack.onLoadingBefore(request);    mOkHttpClient.newCall(request).enqueue(new Callback() {        @Override        public void onFailure(Call call, IOException e) {            mHandler.post(() -> callBack.onFailure(request, e));        }        @Override        public void onResponse(Call call, Response response) throws IOException {            if (response.isSuccessful()) {                mHandler.post(() -> callBack.onSuccess(response));            } else {                mHandler.post(() -> callBack.onError(response));            }        }    });}

结束语

此工具类还没有完善,下篇文章继续完善,待完善内容:返回Resonpse直接解析成javaBean返回。

完整代码

public class OkHttpUtils {    /**     * 网络访问要求singleton     */    private static OkHttpUtils instance;    // 必须要用的okhttpclient实例,在构造器中实例化保证单一实例    private OkHttpClient mOkHttpClient;    public static final MediaType JSON = MediaType.            parse("application/json; charset=utf-8");    private Handler mHandler;    private OkHttpUtils() {        /**         * okHttp3中超时方法移植到Builder中         */        mOkHttpClient = (new OkHttpClient()).newBuilder()                    .connectTimeout(10, TimeUnit.SECONDS)                    .readTimeout(10, TimeUnit.SECONDS)                    .writeTimeout(30, TimeUnit.SECONDS)                    .build();        mHandler = new Handler(Looper.getMainLooper());    }    public static OkHttpUtils getInstance() {        if (instance == null) {            synchronized (OkHttpUtils.class) {                if (instance == null) {                    instance = new OkHttpUtils();                }            }        }        return instance;    }    /**     * 对外提供的Get方法访问     * @param url     * @param callBack     */    public void Get(String url, MyCallBack callBack) {        /**         * 通过url和GET方式构建Request         */        Request request = bulidRequestForGet(url);        /**         * 请求网络的逻辑         */        requestNetWork(request, callBack);    }    /**     * 对外提供的Post方法访问     * @param url     * @param parms: 提交内容为表单数据     * @param callBack     */    public void PostWithFormData(String url, Map<String, String> parms, MyCallBack callBack) {        /**         * 通过url和POST方式构建Request         */        Request request = bulidRequestForPostByForm(url, parms);        /**         * 请求网络的逻辑         */        requestNetWork(request, callBack);    }    /**     * 对外提供的Post方法访问     * @param url     * @param json: 提交内容为json数据     * @param callBack     */    public void PostWithJson(String url, String json, MyCallBack callBack) {        /**         * 通过url和POST方式构建Request         */        Request request = bulidRequestForPostByJson(url, json);        /**         * 请求网络的逻辑         */        requestNetWork(request, callBack);    }    /**     * POST方式构建Request {json}     * @param url     * @param json     * @return     */    private Request bulidRequestForPostByJson(String url, String json) {        RequestBody body = RequestBody.create(JSON, json);        return new Request.Builder()                .url(url)                .post(body)                .build();    }    /**     * POST方式构建Request {Form}     * @param url     * @param parms     * @return     */    private Request bulidRequestForPostByForm(String url, Map<String, String> parms) {        FormBody.Builder builder = new FormBody.Builder();        if (parms != null) {            for (Map.Entry<String, String> entry :                    parms.entrySet()) {                builder.add(entry.getKey(), entry.getValue());            }        }        FormBody body = builder.build();        return new Request.Builder()                .url(url)                .post(body)                .build();    }    /**     * GET方式构建Request     * @param url     * @return     */    private Request bulidRequestForGet(String url) {        return new Request.Builder()                .url(url)                .get()                .build();    }    private void requestNetWork(Request request, MyCallBack callBack) {        /**         * 处理连网逻辑,此处只处理异步操作enqueue         */        callBack.onLoadingBefore(request);        mOkHttpClient.newCall(request).enqueue(new Callback() {            @Override            public void onFailure(Call call, IOException e) {                mHandler.post(() -> callBack.onFailure(request, e));            }            @Override            public void onResponse(Call call, Response response) throws IOException {                if (response.isSuccessful()) {                    mHandler.post(() -> callBack.onSuccess(response));                } else {                    mHandler.post(() -> callBack.onError(response));                }            }        });    }}

定义的接口的完整代码

interface MyCallBack {    void onLoadingBefore(Request request);    void onSuccess(Response response);    void onFailure(Request request, Exception e);    void onError(Response response);}
1 0