okhttp3相关封装配置(三):Callback封装,添加onStart()和onFinish()回调方法

在Android开发框架中,比较重要的一个模块,就是网络请求模块。一个封装比较好的网络请求框架,会让开发者在发送请求和处理回调都十分方便。这篇文章就围绕着使用比较广泛的okhttp3来写,声明一下,本人不是大神,所以封装的并不完善,只是想给大家共享一下这个小小的成果。

我打算以3篇文章来介绍我是怎么封装okhttp3这个框架的,就是围绕着OkHttpClient, request, callback这三个主题来写。

本篇文章来封装Callback。


在介绍Callback之前,我们先准备两样东西。

第一,创建我们自己回调接口。接口中的方法,就是你想在Activity或者Fragment发送请求后,展示出来的回调方法,看代码,更容易理解。

public interface HandleResultListener {

    public void onStart();

    public void onSuccess(JSONObject responseObj);

    public void onFailure(Object obj);

    public void onFinish();
}

看名称应该就很容易理解了,这四个方法执行的时机是:请求开始,请求成功,请求失败,请求结束。
了解okhttp3框架的同僚应该知道,okhttp3的回调方法,只有两个:onResponse()和onFailure()。我添加了onStart()和onFinish(),会方便使用者在发起请求或者请求结束的时候,加些自己的处理逻辑,具体怎么用,等我介绍完另一个准备事物会串讲。

第二,创建异常处理类。我们查看异常的时候,通常都是看msgCode和msg,也就是异常错误码和异常描述信息,所以只声明这两个属性就够了,看代码更易理解。

public class OkHttpException extends Exception {

    private static final long serialVersionUID = 1L;

    private int msgCode;

    private Object msg;

    public OkHttpException(int msgCode, Object msg){
        this.msg = msg;
        this.msgCode = msgCode;
    }

    public int getMsgCode(){
        return msgCode;
    }

    public Object getMsg(){
        return msg;
    }
}

做好准备之后,接下来进行Callback的封装。创建自己的回调处理类实现Callback,我命名为JSONCallback ,JSONCallback implements Callback
实现okhttp3框架Callback的2个回调方法:

public void onFailure(final Call call, final IOException e)
public void onResponse(final Call call, final Response response) throws IOException

这两个方法中该写什么,一会我会贴出我的代码。
先声明2个变量:

    private Handler mUITransHandler;  //进行消息的转发,操作UI线程。
    private HandleResultListener mListener;

创建构造方法和onStart()方法, 构造方法中初始化HandleResultListener 和处理UI的Handler;onStart()方法中,调用HandleResultListener 中的onStart()方法,看代码:

    public JSONCallback(HandleResultListener listener) {
        this.mListener = listener;
        this.mUITransHandler= new Handler(Looper.getMainLooper());
    }

    public void onStart() {
        mListener.onStart();
    }

接下来,开始编写最核心的两个方法:onResponse()和onFailure()

先来处理onResponse()方法,看代码:

    public void onResponse(final Call call, final Response response) throws IOException {

        final String result = response.body().string();
        Log.e("fangming", "responseResult: " + result);
        mUITransHandler.post(new Runnable() {
            @Override
            public void run() {
                handleResult(result);
            }
        });
    }

当请求成功会,这个回调方法就会被执行,但是,只是请求成功,并不代表数据请求成功,所以,我们要对请求返回的数据进行处理。新建一个数据处理方法handleResult(Object result),将返回的数据通过Handler转发到主线程方便我们处理UI。
看一下handleResult()方法的实现:

    private void handleResponse(Object result) {
        //result为null或者为""时,是无法进行后续处理的,直接返回。
        if (result == null || result.toString().trim().equals("")) {
            mListener.onFailure(new OkHttpException(-1, "请求结果为空"));
            return;
        }
        try {
            JSONObject resultObj = new JSONObject(result.toString());
            if (resultObj.has("msgCode") && resultObj.has("msg")) {
                //从JSON对象中取出响应码,O表示成功。
                if (resultObj.getInt("msgCode") == 0) {
                    mListener.onSuccess(resultObj);
                } else {
                    //将服务器返回的msgCode和msg放到异常中返回。
                    mListener.onFailure(new OkHttpException(resultObj.getInt("msgCode"), resultObj.getInt("msg")));
                }
            }else{
                //返回的数据格式不符合要求。
                mListener.onFailure(new OkHttpException(-2, "返回数据格式不合法"));
            }
        } catch (Exception e) {
            mListener.onFailure(new OkHttpException(-3, e.getMessage()));
        }finally {
            //最后调用HandleResultListener中的onFinish()方法。
            mListener.onFinish();
        }
    }

接下来看onFailure()方法:

    public void onFailure(final Call call, final IOException e) {
        mUITransHandler.post(new Runnable() {
            @Override
            public void run() {
                mListener.onFailure(new OkHttpException(-1, e.getMessage()));
                mListener.onFinish();
            }
        });
    }

这个方法很容易理解,只要将异常信息放入我们自定义的异常类中,调用HandleResultListener的onFinish()方法即可。

通过这两个方法,我们可以看出来,不论是请求成功还是失败,都会执行onFinish(),这正是我们要的效果。
下面来实现请求发送之前调用onStart();

在我前面写的okhttp3相关封装配置(一):OkHttpClient的参数配置 这篇文章中,介绍了如何发送Get请求和Post请求。
所以我们只要在发送请求之前执行一下onStart()方法,也就实现了。到目前为止,还有一个问题没有解决,那就是将Callback和请求发送关联在一起。
okhttp3框架中,提供了这样的接口,只需要写一句话就可以实现。


以Get请求为例,看一下OkHttpClient中发送Get请求的完整代码:

    public static Call get(Request request, HandleResultListener listener) {

        JSONCallback callback = new JSONCallback(listener);
        callback.onStart();

        Call call = mOkHttpClient.newCall(request);
        call.enqueue(callback);
        return call;
    }

其中用的Request,在okhttp3相关封装配置(二):Request对象 这篇文章中已经介绍了,使用Request工具类RequestUtil中的(String url, RequestParams params, RequestParams headers)

    public static Call sendGetRequest(String url, RequestParams params, RequestParams headers, HandleResultListener listener){
        return OkHttpClient.get(RequestUtil.
                createGetRequest(url, params, headers), listener);
    }

在Activity中的写法如下:

    private void login() {
        userAccount = login_input_account.getText().toString().trim();
        password = login_input_password.getText().toString().trim();

        RequestParams params = new RequestParams();
        params.put("loginId", userAccount);
        params.put("password", password);

        requestCall = RequestCenter.sendGetRequest(HttpConstants.LOGIN_URL, params, true, new HandleResultListener() {

            @Override
            public void onStart() {
                showLoading();
            }

            @Override
            public void onSuccess(JSONObject responseObj) {
                Log.e("fangming", "onSuccess-----" + responseObj.toString());
            }

            @Override
            public void onFailure(Object obj) {
                Log.e("fangming", "onFailure");
            }

            @Override
            public void onFinish() {
                hideLoading();
            }
        });
    }

这样,okhttp3框架,我就都介绍完了。

你可能感兴趣的:(Android)