您的位置:首页 > 理论基础 > 计算机网络

okhttp +fastJson 在UI层的回调封装

2017-03-17 16:32 204 查看
一直使用OkHttp 经常烦人的地方是回调方法 数据解析后必须通过handler 在主线程做操作 网上找了很多资料 发现有些都是基于Gson做的解析fastJson 在封装时 泛型传入会有很多不方便。想了很久参考着写了如下代码 测试OK!例子是用post方式传递数据首先 封装写了okhttp的统一使用调取接口方法 这个放在了Application里面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); 本人觉得这个可能比弱引用处理的好些。只是封装的写法只会弱引用 不知道还有其他好的方法没 。。


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: