在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框架,我就都介绍完了。