OkHttp简化请求封装思路

936 阅读5分钟

对于OKHttp的封装,现在已经有很多方法,甚至Retrofit也是基于OkHttp封装而来。本文的封装方式不一定是最好的,但相信在某一种场景下肯定能帮助你大大简化代码。

一个普通的请求如下,采用了链式调用,使得可读性大大增加。但是如果一个页面里面有多个请求,代码量也是多很多,而每次请求都要传递参数字段,假如某个字母错了也要回到相应的界面查找。这对于代码强迫症来说是有点接受不了的。

    OkHttpUtils.get()
            .url(UrlAddress.GET_SCENIC_SPOTS)
            .addHeader("authorization",GlobalParams.authorization)
            .addParams("page","1")
            .addParams("pageNum","99999")
            .build()
            .execute(new LiStringCallback() {
                @Override
                public void onBefore(Request request, int id) {
                    super.onBefore(request, id);
              //      showLoadingDialog("获取景区中");
                }
                @Override
                public void onAfter(int id) {
                    super.onAfter(id);
            //        hideLoadingDialog();
                }
                @Override
                public void onError(Call call, Exception e, int i) {
                    super.onError(call, e, i);
                }

                @Override
                public void onResponse(String s, int i) {
                    super.onResponse(s, i);
                    Gson gson = new Gson();
                    //景区列表
                    SceneSpotListResult result = gson.fromJson(s, SceneSpotListResult.class);
                    if (result.checkCode()){
                        sceneList.clear();
                        sceneList.addAll(result.getResult().getData());
                    }
                }
            });

}

简化思路如下,先创建OKHttp封装的接口监听LiOKHttpListen

/**
 * Created by li on 2018/4/10.
 * 这是OKHttp封装的接口监听
 */

public interface LiOKHttpListen {

    /**
     * 访问前
     * @param request  请求数据
     * @param requestType  操作类型
     */
    void onHttpBefore(Request request,RequestType requestType);



    /**
     * 访问后
     * @param requestType 操作类型
     */
    void onHttpAfter(RequestType requestType);



    /**
     * 出错
     * @param e  异常信息
     * @param requestType 操作类型
     */
    void onHttpError(Exception e,RequestType requestType);



    /**
     * 成功
     * @param s 服务器返回数据
     * @param requestType 操作类型
     */
    void onHttpResponse(String s,RequestType requestType);
}

再创建自定义的回调LiStringCallback

/**
 * Created by li on 2018/4/9.
 * 自定义回调
 * 对接口的回调统一在这里进行。
 */

public abstract class LiStringCallback extends StringCallback {

    //大帅比的接口
    private LiOKHttpListen liOKHttpListen;
    //大帅比的操作枚举类型
    private RequestType requestType;

    //普通构造方法
    public LiStringCallback() {
    }

    //带有接口的构造方法
    public LiStringCallback(LiOKHttpListen liOKHttpListen,RequestType requestType) {
        this.liOKHttpListen = liOKHttpListen;
        this.requestType = requestType;
    }


    //请求前操作
    @Override
    public void onBefore(Request request, int id) {
        super.onBefore(request, id);
        if (liOKHttpListen != null) {
            liOKHttpListen.onHttpBefore(request,requestType);
        }
    }

    //请求结束后操作
    @Override
    public void onAfter(int id) {
        super.onAfter(id);

        if (liOKHttpListen != null) {
            liOKHttpListen.onHttpAfter(requestType);
        }
    }

    //请求错误操作
    @Override
    public void onError(Call call, Exception e, int i) {
        //提示网络异常
        MainApp.getInstance().showMsg(R.string.common_string_http_error);

        if (liOKHttpListen != null) {
            liOKHttpListen.onHttpError(e,requestType);
        }
    }

    //请求成功操作
    @Override
    public void onResponse(String s, int i) {
        if (liOKHttpListen != null) {
            liOKHttpListen.onHttpResponse(s,requestType);
        }
    }
}

设置不同操作的枚举类型,RequestType的作用是同个请求可能有不同的操作,需要对之进行区分

/**
 * Created by li on 2018/4/10.
 * 枚举类。包括需要进行的操作,用于判断不同操作
 */

public enum RequestType {
    GET_SCENE    // 获取景


存放键值对数据的实体,仅方便数组请求


/**
 * Created by li on 2018/4/10.
 * 存放键值对数据的实体
 */

public class LiKeyBean {
    //键名
    String keyName;
    //键值
    String keyValue;

    public LiKeyBean(String keyName, String keyValue) {
        this.keyName = keyName;
        this.keyValue = keyValue;
    }

    public String getKeyName() {
        return keyName;
    }

    public void setKeyName(String keyName) {
        this.keyName = keyName;
    }

    public String getKeyValue() {
        return keyValue;
    }

    public void setKeyValue(String keyValue) {
        this.keyValue = keyValue;
    }
}

最后是okhttp管理类

/**
 * Created by li on 2018/4/10.
 * 面对用户使用的方法,可用post等方法
 * 用户调用对应方法,并实现接口即可
 */

public class LiOKHttpUtil {




    /**
     * 用数据请求 post
     * @param listen 实现LiOKHttpListen接口的对象
     * @param url    链接
     * @param heads  请求头数组
     * @param params  参数数组
     * @param requestType  操作类型
     */
    private static void post(LiOKHttpListen listen,String url,LiKeyBean[] heads, LiKeyBean[] params ,RequestType requestType){
        //获取build
        PostFormBuilder postFormBuilder =  OkHttpUtils.post().url(url);
        //添加请求头
        if (heads!=null){
            for (int i=0;i<heads.length;i++){
                LiKeyBean keyBean = heads[i];
                if (keyBean==null) continue;
                postFormBuilder.addHeader(keyBean.getKeyName(),keyBean.getKeyValue());

            }
        }
        //添加请求
        if (params!=null){
            for (int i=0;i<params.length;i++){
                LiKeyBean keyBean = params[i];
                if (keyBean==null) continue;
                postFormBuilder.addParams(keyBean.getKeyName(),keyBean.getKeyValue());
            }
        }

        //请求
        postFormBuilder .build().
                execute(new LiStringCallback(listen,requestType) {
                    @Override
                    public void onBefore(Request request, int id) {
                        super.onBefore(request, id);
                    }

                    @Override
                    public void onAfter(int id) {
                        super.onAfter(id);
                    }

                    @Override
                    public void onError(Call call, Exception e, int i) {
                        super.onError(call, e, i);
                    }

                    @Override
                    public void onResponse(String s, int i) {
                        super.onResponse(s, i);
                    }
                });
    }


    /**
     * 用数据请求 get
     * @param listen 实现LiOKHttpListen接口的对象
     * @param url    链接
     * @param heads  请求头数组
     * @param params  参数数组
     * @param requestType  操作类型
     */
    private static void get(LiOKHttpListen listen, String url,LiKeyBean[] heads, LiKeyBean[] params ,RequestType requestType){
        //获取build
        GetBuilder getBuilder =  OkHttpUtils.get().url(url);
        //添加请求头
        if (heads!=null){
            for (int i=0;i<heads.length;i++){
                LiKeyBean keyBean = heads[i];
                if (keyBean==null) continue;
                getBuilder.addHeader(keyBean.getKeyName(),keyBean.getKeyValue());

            }
        }
        //添加请求
        if (params!=null){
            for (int i=0;i<params.length;i++){
                LiKeyBean keyBean = params[i];
                if (keyBean==null) continue;
                getBuilder.addParams(keyBean.getKeyName(),keyBean.getKeyValue());
            }
        }

        //请求
        getBuilder .build().
                execute(new LiStringCallback(listen,requestType) {
                    @Override
                    public void onBefore(Request request, int id) {
                        super.onBefore(request, id);
                    }

                    @Override
                    public void onAfter(int id) {
                        super.onAfter(id);
                    }

                    @Override
                    public void onError(Call call, Exception e, int i) {
                        super.onError(call, e, i);
                    }

                    @Override
                    public void onResponse(String s, int i) {
                        super.onResponse(s, i);
                    }
                });
    }

    /**
     * 用事先封装好的GetBuilder进行get请求
     * @param listen  实现LiOKHttpListen接口的对象
     * @param getBuilder 事先封装好的GetBuilder
     * @param requestType 操作类型
     */
    private static void get(LiOKHttpListen listen,GetBuilder getBuilder ,RequestType requestType){
        //请求
        getBuilder.build().
                execute(new LiStringCallback(listen,requestType) {
                    @Override
                    public void onBefore(Request request, int id) {
                        super.onBefore(request, id);
                    }

                    @Override
                    public void onAfter(int id) {
                        super.onAfter(id);
                    }

                    @Override
                    public void onError(Call call, Exception e, int i) {
                        super.onError(call, e, i);
                    }

                    @Override
                    public void onResponse(String s, int i) {
                        super.onResponse(s, i);
                    }
                });
    }
    /**
     * 用事先封装好的PostFormBuilder进行post请求
     * @param listen  实现LiOKHttpListen接口的对象
     * @param postFormBuilder 事先封装好的PostFormBuilder
     * @param requestType 操作类型
     */
    private static void post(LiOKHttpListen listen,PostFormBuilder postFormBuilder ,RequestType requestType){
        //请求
        postFormBuilder.build().
                execute(new LiStringCallback(listen,requestType) {
                    @Override
                    public void onBefore(Request request, int id) {
                        super.onBefore(request, id);
                    }

                    @Override
                    public void onAfter(int id) {
                        super.onAfter(id);
                    }

                    @Override
                    public void onError(Call call, Exception e, int i) {
                        super.onError(call, e, i);
                    }

                    @Override
                    public void onResponse(String s, int i) {
                        super.onResponse(s, i);
                    }
                });
    }


    /**
     * 获取景区
     * @param listen
     */
    public static void getScenes(LiOKHttpListen listen,RequestType requestType) {

        GetBuilder getBuilder =  OkHttpUtils.get()
                .url(UrlAddress.GET_SCENIC_SPOTS)
                .addHeader("authorization",GlobalParams.authorization)
                .addParams("page","1")
                .addParams("string","99999");
        get(listen,getBuilder,requestType);
    }

}

到这一步就可以在activity里面请求了

public class MainActivity extends BaseActivity implements LiOKHttpListen {


    @Override
    protected int getLayoutId() {
        return R.layout.main_activity_main;
    }

    @Override
    protected void initViews() {
     }

    @Override
    protected void onDestroy() {
    }

    @Override
    protected void initDatas() {
        getScenes();

    }

    @Override
    protected void showContent() {

    }


    /**
     * 获取全部景区
     */
    public void getScenes(){
        //一行代码就可以请求
       LiOKHttpUtil.getScenes(this,RequestType.GET_SCENE);

    }

    @Override
    public void onHttpBefore(Request request, RequestType requestType) {
        switch (requestType){
            case GET_SCENE:
                showLoadingDialog("获取景区中");
                break;
        }
    }

    @Override
    public void onHttpAfter(RequestType requestType) {
    //隐藏弹窗
        hideLoadingDialog();
    }

    @Override
    public void onHttpError(Exception e, RequestType requestType) {

    }

    @Override
    public void onHttpResponse(String s, RequestType requestType) {
        switch (requestType){
            case GET_SCENE:
                //获取成功后的操作
                break;
        }

    }


}

通过以上操作就实现了笔者想要的目的,总结如下 1.抛弃了原本单个请求就可以看到全部处理的可读性,改成了全部请求通过接口返回,适用于大部分对除response之外操作不多或者重复的请求 2.将所有请求的大任都交给了LiOkHttpUtil的工具类,方便对请求管理