android okhttp工具类,基于鸿洋okhttp封装工具类okhttputils 返回数据回调封装-Go语言中文社区...

本文介绍了如何基于OkHttpUtils进行二次封装,以适应不同数据格式的网络请求。通过创建一个请求结果基类和通用Callback,简化了处理多种数据结构的过程,降低了代码冗余。同时,详细展示了如何处理网络错误、数据转换和泛型回调的使用,使得在网络请求中更加灵活和高效。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简介

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

{

//非UI线程,支持任何耗时操作

@Override

public 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 extends BaseBean{

private List results;

public List getResults() {

return results;

}

public void setResults(List results) {

this.results = results;

}

}

如果数据集合有其他键值的 直接在本类中新加集合即可

比如还有另一个接口返回的时下面的数据

{“error”:”false”,”body”:[…]}

则增加一个新键值,获取数据时注意键值不要选错

public class ResultData extends BaseBean{

private List results;

private List body;

public List getResults() {

return results;

}

public void setResults(List results) {

this.results = results;

}

public List getBody() {

return body;

}

public void setBody(List 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 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>(){

@Override

public void onResponse(ResultData response, int id) {

if (!response.error) {

mDataBinding.tv.setText( response.getResults().get(0).get_id());

}

}

});

}

获取数据情况,我们的确拿到了数据

7e027d3e1bc055fbad5dd27b9ceb6de1.png

我们来看一些与第一个api获取数据对比

09ffcd3a4726b88a15f748dc08f57f92.png

图片看的不太清除

这里解释下,大家也可以去通过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>(){

@Override

public void onResponse(ResultData response, int id) {

if (!response.error) {

mDataBinding.tv.setText( response.getResults().get(0).get_id());

}

}

});

}

再来看一下结果

95e95a6d360e84997a45bd4bf61dfba3.png

同样时拿到了id

框架搭好后,对于新的后台接口,只需创建一个新的 返回的数据集合中的bean,传入泛型即可

方便好用

看一下结构

1357ad6a586c35bf929b866555c8a9ba.png

项目使用的依赖

compile 'com.zhy:okhttputils:2.6.2'

compile 'com.google.code.gson:gson:2.8.0'

参考文章

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值