之前使用okhttputil,由于鸿洋的该框架并未对于回调数据进行过度处理,callback需要自定义处理,所以在项目使用时对其进行了封装,后来发现OkGo对于Callback进行了封装,自己的封装Callback和OkGo的有些相似,然后在新的项目中就使用基于OkGo二次封装的网络请求框架了,这里主要介绍OkGo的基于MVC下的二次封装和使用
本文案例的项目地址 https://github.com/caixingcun/OkGoDemo
OkGo地址 https://github.com/jeasonlzy/okhttp-OkGo/wiki
OkHttpUtil 地址 https://github.com/hongyangAndroid/okhttputils
现在的网络框架正常都是使用的json从后台获取数据,这里保存RESTful风格
这里需要首先跟后台约定好传递数据的格式
常规数据格式
{
"Code":100,
"Msg":"请求成功",
"Result":{
"Name":"老王"
}
}
常规错误数据格式
{
"Code":101,
"Msg":"请求失败",
}
数组数据
{
"Code":100,
"Msg":"请求成功",
"Result":[
{
"Name":"老王",
"Age":23
},
{
"Name":"老李",
"Age":25
}
]
}
数组请求为空
{
“Code”:100,
“Msg”:”请求成功”,
“Result”:[]
}
1.添加依赖
compile ‘com.readystatesoftware.chuck:library:1.0.4’
compile ‘com.readystatesoftware.chuck:library:1.0.4’
2.App中初始化
有特定需求的可以按okgo文档配置
OkGo.getInstance().init(this);
将demo下callback中的内容复制进自己的项目
这部分是作者编写的可供修改的框架部分
有报错基本就是类不存,或者重写import
把相关类复制进来
可以看一下当前复制进来的主要几个类
Convert.java 转换
JsonConvert.java 带泛型转换
JsonCallback.java 泛型转换回调
LzyResponse.java 实体类
SimpleResponse.java
顾名思义 也可以看出这些类的大概意思
基本上Convert就是基本的Gson转换
JsonConvert就是再上面的基础上对于网络请求数据进行了初步处理
这里已经在分析返回错误码
也就是我们最上面定义的{“Code”:101,”Msg”:”“}
我们来看一下作者的转换类 LzyResponse.java
基本格式实际上是跟我们统一的
再看一下JsonCallback.java
应该是对于传递的泛型进行分类型处理
我这里先使用node.js创建一个本地简易网络访问服务器
创建一组json请求数据
OkGo.<String>get("http://192.168.1.79:3000/simplerequest")
.execute(new StringCallback(){
@Override
public void onSuccess(Response<String> response) {
tv.setText(response.body());
}
});
注意上面的是大写的Code
下面添加一串跟OkGo中Lzy相同的数据结构,并请求
OkGo.get("http://192.168.1.79:3000/okgoget")
.execute(new JsonCallback() {
@Override
public void onSuccess(Response response) {
tv.setText(response.body().msg);
}
});
整改开始,就是将作者所给框架的code msg修改为跟我们后台约定一样的格式
改了LzyResponse和SimpleResponse,JsonConvert就可以了,很快
再来通过作者的二次框架来访问大写Code Msg
但是要知道为什么自己要进行二次封装网络框架
正常的StringCallback也可以进行网络请求,就是因为方便
这里需要使用LzyResponse
然后对于JsonConvert和JsonCallback进行整改
当我们使用LzyRespose接收数据时,会发现我们拿不到我们的数据,在Callback回调中
数据
{"Code":104,"Msg":"授权无效"}
代码
OkGo.>get("http://192.168.1.79:3000/okgo104")
.execute(new JsonCallback>(){
@Override
public void onSuccess(Response> response) {
tv.setText(response.body().Msg+response.body().Code);
}
});
在访问后台总会发生各种问题,尤其时身份问题
还有各种错误,这些东西需要统一处理
看下JsonConvert的源码
int code = lzyResponse.Code;
//这里的0是以下意思
//一般来说服务器会和客户端约定一个数表示成功,其余的表示失败,这里根据实际情况修改
if (code == 0) {
//noinspection unchecked
return (T) lzyResponse;
} else if (code == 104) {
throw new IllegalStateException("用户授权信息无效");
} else if (code == 105) {
throw new IllegalStateException("用户收取信息已过期");
} else {
//直接将服务端的错误信息抛出,onError中可以获取
throw new IllegalStateException("错误代码:" + code + ",错误信息:" + lzyResponse.Msg);
}
我们在这里只需要将和后台约定的Code状况都添加进来
也可以像我之前的代码
抛出自定义异常 然后统一到onError中处理
int code = responseBean.Code;
String msg = responseBean.Msg;
//这里的0是以下意思
//一般来说服务器会和客户端约定一个数表示成功,其余的表示失败,这里根据实际情况修改
//这里的异常会抛到 JsonCallback中 的onError
if (code == 0 || code == 103) {
//noinspection unchecked
return (T) responseBean;
} else {
throw new MyException("{\"Code\":"+code+",\"Msg\":\""+msg+"\"}");
}
在JsonCallback中重写onError进行异常处理
需要注意onError回调中response.code()是网络请求的code
不是我们数据中的code
if (code == 100) {
return (T) lzyResponse;
} else {
throw new MyException("{\"Code\":"+code+",\"Msg\":\""+msg+"\"}");
}
MyException
public class MyException extends IllegalStateException {
private LzyResponse errorBean;
public MyException(String s) {
super(s);
errorBean = new Gson().fromJson(s, LzyResponse.class);
}
public LzyResponse getErrorBean() {
return errorBean;
}
}
JsonCallback中 onError
@Override
public void onError(com.lzy.okgo.model.Response response) {
super.onError(response);
int code = response.code();
if (code == 404) {
Log.d("JsonCallback", "404 当前链接不存在");
}
if (response.getException() instanceof SocketTimeoutException) {
Log.d("JsonCallback", "请求超时");
} else if (response.getException() instanceof SocketException) {
Log.d("JsonCallback", "服务器异常");
} else if (response.getException() instanceof MyException) {
switch (((MyException) response.getException()).getErrorBean().Code) {
case 107: //约定的身份表示过期
//重登录
break;
}
}
}
对于回调封装到这里就结束了
外部调用简单封装
public class OkGoUtil {
public static <T> void getRequets(String url, Object tag, Map<String, String> map, JsonCallback<T> callback) {
// TODO: 2017/10/13 加密 时间戳等 请求日志打印
Log.d("OkGoUtil", "method get");
OkGo.<T>get(url)
.tag(tag)
.params(map)
.execute(callback);
}
public static <T> void postRequest(String url, Object tag, Map<String, String> map, JsonCallback<T> callback) {
// TODO: 2017/10/13 加密 时间戳等 请求日志打印
Log.d("OkGoUtil", "method post");
OkGo.<T>post(url)
.tag(tag)
.params(map)
.execute(callback);
}
}
来看一下调用情况
接口
http://localhost:3000/api/post
数据
{"Code":100,
"Msg":"请求成功",
"Result":{"name":"老王","hobby":"爱吃鸡"}
}
新建数据bean
public class SimpleBean {
/**
* name : 老王
* habby : 吃鸡
*/
private String name;
private String habby;
}
get set方法这里不贴
请求
OkGoUtil.getRequets("http://192.168.1.79:3000/okgo_get", this, new HashMap<String, String>(), new JsonCallback>() {
@Override
public void onSuccess(Response> response) {
tv.setText(response.body().Result.getName() + "-" + response.body().Result.getHabby());
}
});
好了封装完毕
之后每次使用 只需要将Result中数据bean创建出来
其他所有异常 在与后台约定好后通过Code 在JsonCallback中的onError中进行处理即可
在onSuccess中只处理 Code = 100的正常情况
如果有需要在主线程需要做什么特殊处理
在调用时的Callback中重写onError也是可以拿到具体的错误数据的