基于鸿洋okhttp封装工具类okhttputils 返回数据回调封装
来源:互联网 发布:qq飞车白银雷诺数据 编辑:程序博客网 时间:2024/05/21 15:43
简介
okhttputils 是csdn 鸿洋大神基于okhttp网络请求进行的二次封装
基本请求格式如下
OkHttpUtils.get().url(url).addParams("username", "hyman").addParams("password", "123").build().execute(callback);
工具类中提供了 集中callback回调 可以直接获取转换后的数据类型
比如String bitmap
当然也可以自定义,只需要继承工具类中的Callback,然后通过Gson
及自己创建的数据类字节码 进行转化
public abstract class UserCallback extends Callback<User>{//非UI线程,支持任何耗时操作@Overridepublic User parseNetworkResponse(Response response) throws IOException{ String string = response.body().string(); User user = new Gson().fromJson(string, User.class); return user;}}
再将该自定义Callback传入请求的execute方法即可
总之这个工具类很方便,具体参开上面的链接
问题
不是说工具类有问题
而是在实际项目中,获取的数据格式各不相同,每一种数据格式就需要新建一个数据bean,对应数据bean还需要创建对应Callback
这就会使得一个业务新建的类太多
遇到一堆业务时,定义的类的数量爆炸
然而数据bean的基本都会有success标志 以及 msg 提示消息
以一个开源网络api为例 Gank的网站提供的api为例 http://gank.io/api/data/Android/10/1
基本格式就是 下面这样一个json
一般都是一个请求标记位 + 数据集合
{“error”:false,
“results”:[{… }]}
并且Callback回调中的 onError 和 onResponse处理很多感觉又可以复用
.execute(new BitmapCallback(){ @Override public void onError(Request request, Exception e) { //根据错误类型决定展示错误界面 } @Override public void onResponse(Bitmap bitmap) { //关闭正在加载界面,展示加载好数据的界面 }});
这里做的就是对于对于不同数据bean的处理,以及回掉函数callback的封装,便于应对各种问题
先创建了一个请求结果基类,只包含请求结果,对应gank的json数据
public class BaseBean { /** * error : false */ public String error;}
然后直接通过GsonFormat插件复制整个gank 的json数据
自动生成获取整个数据的bean ResultData
然后让其继承BaseBean 将其中集合部分 ResultsBean 换成泛型
下面就是修改后的数据bean
只要返回json类型为 error + results类型的只需要新建一个results集合
中的子类数据bean将其传入本来即可,用本类来接收整个数据
public class ResultData<T> extends BaseBean{ private List<T> results; public List<T> getResults() { return results; } public void setResults(List<T> results) { this.results = results; }}
如果数据集合有其他键值的 直接在本类中新加集合即可
比如还有另一个接口返回的时下面的数据
{“error”:”false”,”body”:[…]}
则增加一个新键值,获取数据时注意键值不要选错
public class ResultData<T> extends BaseBean{ private List<T> results; private List<T> body; public List<T> getResults() { return results; } public void setResults(List<T> results) { this.results = results; } public List<T> getBody() { return body; } public void setBody(List<T> body) { this.body = body; }}
当然也可以和后端商量,返回数据中集合部分统一用results或者body
就不需要额外添加键值了
有时候,还可能有下面这种数据
{“error”: false , “result”:[…],”count”: 100}
多了一个字段 count
那么就在基类BaseBean中加上这个字段,其他完全不需要变动
public class BaseBean { /** * error : false */ public String error; public int count;}
数据bean基本处理完了
下面来实现对于callback封装
先写一个BaseCallback我们可以在这里将部分网络错误处理掉
比如登陆过期,无网络访问,返回404等
还可以在这里关闭加载中界面(我在项目中加载中界面是一个全局的dialog)
public abstract class BaseCallback extends Callback{ @Override public void onError(Call call, Exception e, int id) { // TODO: }}
查看了OkhttpUtils封装源码,发现网络请求的code 如404等会被放在
异常类的最后,就是onError中的回掉参数e
下面重点来了,数据类型转换,二次封装callback
这里主要进行数据类型转换,这个类直接拿来用就可以了
没什么变动的地方
public abstract class ResponseCallback<T> extends BaseCallback { public Type mType; public ResponseCallback() { mType = getSuperclassTypeParameter(getClass()); } static Type getSuperclassTypeParameter(Class<?> subclass) { Type superclass = subclass.getGenericSuperclass(); if (superclass instanceof Class) { throw new RuntimeException("Missing type parameter."); } ParameterizedType parameterized = (ParameterizedType) superclass; return $Gson$Types.canonicalize(parameterized.getActualTypeArguments()[0]); } @Override public T parseNetworkResponse(Response response, int id) throws Exception { return new Gson().fromJson(response.body().string(), mType); }}
传入泛型,帮你转换
最后我们来尝试一把 看使用情况
直接访问网络,传入ResponseCallback
传入泛型ResultData < ResultBean >
private void getData() { OkHttpUtils .get() .url("http://gank.io/api/data/Android/3/1") .build() .execute(new ResponseCallback<ResultData<ResultBean>>(){ @Override public void onResponse(ResultData<ResultBean> response, int id) { if (!response.error) { mDataBinding.tv.setText( response.getResults().get(0).get_id()); } } }); }
获取数据情况,我们的确拿到了数据
再换个api试试 http://gank.io/api/history/content/day/2016/05/11
我们来看一些与第一个api获取数据对比
图片看的不太清除
这里解释下,大家也可以去通过api访问比对
{“error”:false,”result”:[…]} 一致 但 数组中内容格式完全不同
根据新数据结构创建新数据bean resultbean1
public class ResultBean1 { private String _id; private String content; private String publishedAt; private String title; public String get_id() { return _id; } public void set_id(String _id) { this._id = _id; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public String getPublishedAt() { return publishedAt; } public void setPublishedAt(String publishedAt) { this.publishedAt = publishedAt; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; }}
然后再次访问,与上次只有url 和 ResultData中传入的泛型不一致,其他直接复制过来的
private void getData1() { OkHttpUtils .get() .url("http://gank.io/api/history/content/day/2016/05/11") .build() .execute(new ResponseCallback<ResultData<ResultBean1>>(){ @Override public void onResponse(ResultData<ResultBean1> response, int id) { if (!response.error) { mDataBinding.tv.setText( response.getResults().get(0).get_id()); } } }); }
再来看一下结果
同样时拿到了id
框架搭好后,对于新的后台接口,只需创建一个新的 返回的数据集合中的bean,传入泛型即可
方便好用
看一下结构
项目使用的依赖
compile 'com.zhy:okhttputils:2.6.2' compile 'com.google.code.gson:gson:2.8.0'
源码下载地址
参考文章
鸿洋okhttputils网络访问框架
okhttp简单封装
- 基于鸿洋okhttp封装工具类okhttputils 返回数据回调封装
- Okhttp工具类封装
- Okhttp封装工具类
- 封装OkHttp工具类
- okhttp封装工具类
- 封装OKHttp,工具类
- OkHttpUtils - 封装了okhttp的网络框架
- OkHttpUtils - 封装了okhttp的网络框架
- OkHttpUtils - 封装了okhttp的网络框架
- OkHttpUtils - 封装了okhttp的网络框架
- okhttputils封装
- OKhttp二次封装工具类
- OkHttpUtils已封装好的工具类+依赖,直接使用
- 封装封装OkHttpUtils
- 基于OkHttpUtils再次封装代码最简化
- OkHttp网络连接封装工具类
- 非常简单的OKhttp封装工具类
- okhttp传输封装的工具类
- Spring Boot热部署(springloader)
- 排序算法之选择排序
- 22 WebGL使用多幅纹理
- javaScript的数据类型
- Leetcode练习<十> 列表元素去重
- 基于鸿洋okhttp封装工具类okhttputils 返回数据回调封装
- ubuntu + anaconda + tensorflow
- mysql中使得多张表的ID不重复
- tensorflow入门(4)逻辑回归分类器
- 教你用最新工具反编译android apk
- apache下开启ssl访问,即https
- Android studio APP签名打包
- Hive 中的 LEFT SEMI JOIN 与 JOIN ON 的前世今生
- Java笔试题解(10)