一直使用OkHttp 常常煩人的地方是回調方法 數據解析後必須經過handler 在主線程作操做 網上找了不少資料 發現有些都是基於Gson作的解析 java
fastJson 在封裝時 泛型傳入會有不少不方便。想了好久參考着寫了以下代碼 測試OK!例子是用post方式傳遞數據 android
首先 封裝寫了okhttp的統一使用調取接口方法 這個放在了Application裏面json
url是接口地址 object是請求的參數對象 params是和後臺定義好的參數傳遞方式 。 最後就是最主要的回調方法了!數據結構
public <T> void doPostAsyncfilexx(String url, T object, OkhttpCallbackUtils callback) {
Log.d("CD", "url=="+url+"==params=="+JSON.toJSONString(object));
RequestBody requestBody = new FormBody.Builder()
.add("params", JSON.toJSONString(object))
// .add("phone", "13808892360")
// .add("password", "123")
.build();
Request request = new Request.Builder()
.url(url)
.post(requestBody)
.build();
mOkHttpClient.newCall(request).enqueue(callback);
}
回調類OkhttpCallbackUtils
package com.example.admin.hhh_zhjg.utils;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.example.admin.hhh_zhjg.responsebean.BaseBeanRsp;
import java.io.IOException;
import java.lang.ref.WeakReference;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;
public class OkhttpCallbackUtils<T> implements Callback {
private TypeReference<BaseBeanRsp<T>> mClazz;
protected OkhttpCallbackUtils(TypeReference<BaseBeanRsp<T>> mClazz) {
if (mClazz == null) {
throw new IllegalArgumentException("response can't be null");
}
this.mClazz = mClazz;
}
@Override
public void onFailure(Call call, IOException e) {
Message message = Message.obtain();
message.what = ConValue.MSG_FAIL;
message.obj = e;
mHandler.sendMessage(message);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
String body = response.body().string();
//fastjison fastjson 解析多級泛型時而失敗 解析 對泛型最多隻能解析一層泛型數據 泛型多層嵌套沒法解析內部泛型
//分析後要傳人整個TypeReference<T>
BaseBeanRsp<T> mResponse = JSON.parseObject(body, mClazz);
//mResponse = JSON.parseObject(body,type);
Log.d("CD","DDDDJSOM="+JSON.toJSONString(mResponse));
Message message = Message.obtain();
message.what = ConValue.MSG_SUCESS;
message.obj = mResponse;
mHandler.sendMessage(message);
} else {
Message message = Message.obtain();
message.what = ConValue.MSG_FAIL;
mHandler.sendMessage(message);
}
}
//hander 的處理
private Handler mHandler = new UIHandler(this);
private static class UIHandler<T> extends Handler {
//handler 弱引用
private WeakReference mWeakReference;
private UIHandler(OkhttpCallbackUtils callback) {
super(Looper.getMainLooper());
mWeakReference = new WeakReference(callback);
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case ConValue.MSG_SUCESS: {
BaseBeanRsp<T> t = (BaseBeanRsp<T>) msg.obj;
OkhttpCallbackUtils callback = (OkhttpCallbackUtils) mWeakReference.get();
if (callback != null) {
callback.onResponse(t);
}
break;
}
case ConValue.MSG_FAIL: {
IOException e = (IOException) msg.obj;
OkhttpCallbackUtils callback = (OkhttpCallbackUtils) mWeakReference.get();
if (callback != null) {
callback.onFailure(e);
}
break;
}
default:
super.handleMessage(msg);
break;
}
}
}
//增長兩個外面調用處理的方法
public void onResponse(BaseBeanRsp<T> t) {
}
public void onFailure(IOException e) {
}
}
OK 這樣的方式 在數據類型是多個泛型時就不會有問題了, 接下來就是在獲取數據時的調用了
private void getData() {
GetMeasureListReq req = new GetMeasureListReq();
req.sectionCode=sectionCode;
req.pageno=pageIndex+"";
req.pagesize=pagesize+"";
上面這個是我寫的請求數據類 能夠不用管,下面纔是調用方法
ConValue.URL+ConValue.MEASURELIST 是接口url
注意回調方法
BaseBeanRsp<GetMeasureListRsp>是接收到的數據類型 在作的項目返回數據有點繁雜因此寫了兩個嵌套的數據結構
BaseBeanRsp<> 是大的數據結構 框架通常是不變的,
GetMeasureListRsp是嵌套的數據結構 返回數據類型根據你本身的數據定義
App.getInstance().doPostAsyncfilexx(ConValue.URL+ConValue.MEASURELIST,req,new OkhttpCallbackUtils<GetMeasureListRsp>(new TypeReference<BaseBeanRsp<GetMeasureListRsp>>(){}){
@Override
public void onResponse(BaseBeanRsp<GetMeasureListRsp> t) {
super.onResponse(t);
Toast.makeText(getActivity(), "獲取數據OK !", Toast.LENGTH_SHORT).show();
主UI處理代碼寫這裏
}
@Override
public void onFailure(IOException e) {
super.onFailure(e);
Toast.makeText(getActivity(), "獲取數據失敗!", Toast.LENGTH_SHORT).show();
}
});
}
只要這三步 後面接口拿數據 和主線程UI處理是否是方便 清楚不少,就不用每次都寫一遍okhttp的調用和handler方法了。最後在說下 handler用的弱引用, 在以前寫的方法是在nDestroy() 中用mHandler.removeCallbacksAndMessages(null); 本人以爲這個可能比弱引用處理的好些。只是封裝的寫法只會弱引用 不知道還有其餘好的方法沒 。。