RxJava+Retrofit+OkHttp深入浅出终极封装六特殊篇变种String替换Gson自由扩展.docx

上传人:b****6 文档编号:6326408 上传时间:2023-01-05 格式:DOCX 页数:13 大小:96.30KB
下载 相关 举报
RxJava+Retrofit+OkHttp深入浅出终极封装六特殊篇变种String替换Gson自由扩展.docx_第1页
第1页 / 共13页
RxJava+Retrofit+OkHttp深入浅出终极封装六特殊篇变种String替换Gson自由扩展.docx_第2页
第2页 / 共13页
RxJava+Retrofit+OkHttp深入浅出终极封装六特殊篇变种String替换Gson自由扩展.docx_第3页
第3页 / 共13页
RxJava+Retrofit+OkHttp深入浅出终极封装六特殊篇变种String替换Gson自由扩展.docx_第4页
第4页 / 共13页
RxJava+Retrofit+OkHttp深入浅出终极封装六特殊篇变种String替换Gson自由扩展.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

RxJava+Retrofit+OkHttp深入浅出终极封装六特殊篇变种String替换Gson自由扩展.docx

《RxJava+Retrofit+OkHttp深入浅出终极封装六特殊篇变种String替换Gson自由扩展.docx》由会员分享,可在线阅读,更多相关《RxJava+Retrofit+OkHttp深入浅出终极封装六特殊篇变种String替换Gson自由扩展.docx(13页珍藏版)》请在冰豆网上搜索。

RxJava+Retrofit+OkHttp深入浅出终极封装六特殊篇变种String替换Gson自由扩展.docx

RxJava+Retrofit+OkHttp深入浅出终极封装六特殊篇变种String替换Gson自由扩展

RxJava+Retrofit+OkHttp深入浅出-终极封装六特殊篇(变种String替换Gson自由扩展)

通过传统的GsonConverterFactory自动解析,这样做确实很方便,用户能直接获取返回的对象,不用关心具体的转换,但是:

这随之而来有很多的缺陷(虽然官网推荐这样使用);

比如:

无法使用其他第三发转换框架;泛型无法中间传递,封装无法统一处理缓存结果;回调信息无法统一处理;服务器返回格式不严谨null解析异常……….

所以我们在享受它遍历的同时也被迫的要限制做很多的处理,限制我们的扩展!

本章就介绍如何放弃GsonConverterFactory,直接返回String,扩展我们的封装!

(封装的整体思想和之前的封装一样,所以不会有大的改动!

无须担心,本篇封装单独作为一个项目和之前封装分开,便于大家选择!

功能

完全具备和之前封装一样的功能,这里改用fastjson处理

1.Retrofit+Rxjava+okhttp基本使用方法

2.统一处理请求数据格式

3.统一的ProgressDialog和回调Subscriber处理

4.取消http请求

5.预处理http请求

6.返回数据的统一判断

7.失败后的retry处理

8.RxLifecycle管理生命周期,防止泄露

9.文件上传下载(支持多文件,断点续传)

10.Cache数据持久化和数据库(greenDao)两种缓存机制

11.一对多回调接口处理

对比

话说没有比较就没有进步,所以大家比较下前后封装的各自的优缺点,自行选择合适自己的方案!

使用

Gson方案:

//完美封装简化版

privatevoidsimpleDo(){

SubjectPostApipostEntity=newSubjectPostApi(simpleOnNextListener,this);

postEntity.setAll(true);

HttpManagermanager=HttpManager.getInstance();

manager.doHttpDeal(postEntity);

}

//回调一一对应

HttpOnNextListenersimpleOnNextListener=newHttpOnNextListener>(){

@Override

publicvoidonNext(Listsubjects){

tvMsg.setText("网络返回:

\n"+subjects.toString());

}

@Override

publicvoidonCacheNext(Stringcache){

/*缓存回调*/

Gsongson=newGson();

java.lang.reflect.Typetype=newTypeToken>>(){}.getType();

BaseResultEntityresultEntity=gson.fromJson(cache,type);

tvMsg.setText("缓存返回:

\n"+resultEntity.getData().toString());

}

/*用户主动调用,默认是不需要覆写该方法*/

@Override

publicvoidonError(Throwablee){

super.onError(e);

tvMsg.setText("失败:

\n"+e.toString());

}

/*用户主动调用,默认是不需要覆写该方法*/

@Override

publicvoidonCancel(){

super.onCancel();

tvMsg.setText("取消請求");

}

};

String方案

//完美封装简化版

privatevoidsimpleDo(){

/*初始化数据*/

manager=newHttpManager(this,this);

postEntity=newSubjectPostApi();

postEntity.setAll(true);

manager.doHttpDeal(postEntity);

}

@Override

publicvoidonNext(Stringresulte,Stringmothead){

/*post返回处理*/

if(mothead.equals(postEntity.getMothed())){

ListsubjectResulte=JSONObject.parseArray(resulte,SubjectResulte.class);

tvMsg.setText("post返回:

\n"+subjectResulte.toString());

}

/*上传返回处理*/

if(mothead.equals(uplaodApi.getMothed())){

UploadResulteuploadResulte=JSONObject.parseObject(resulte,UploadResulte.class);

tvMsg.setText("上传成功返回:

\n"+uploadResulte.getHeadImgUrl());

Glide.with(MainActivity.this).load(uploadResulte.getHeadImgUrl()).skipMemoryCache(true).into(img);

}

}

@Override

publicvoidonError(Throwablee){

tvMsg.setText("失败:

\n"+e.toString());

}

Gson封装方案中,我们采用了一一对应的返回原则,将所以的请求数据参数都放入到baseApi中,返回放入对应的HttpOnNextListener中

String方案中我们则采用一对多原则,将回调和请求分开处理,公用一个回调,通过回调中的mothead来区分不同的接口,所以上述可以看见后者里面其实还处理了上传的回调处理!

从封装的用法上可以看出:

优点:

String封装更加的灵活,可以指定Gson转换的第三方工具,统一的结果返回处理代码更加的少(可以完美解决缓存无法统一回调的问题);

同样也有缺点:

String封装无法自动解析结果类型,需要手动处理(我反而觉得这也是它的优点,更加的灵活,个人看法)

1.替换GsonConverterFactory

由于GsonConverterFactory会自动解析Gson,替换成直接返回String的ScalarsConverterFactory

导入相关包(为了区别-使用fastjson可自由扩展)

compile'com.squareup.retrofit2:

converter-scalars:

+'

compile'com.alibaba:

fastjson:

+'

替换

compile'com.squareup.retrofit2:

converter-gson:

+'

compile'com.google.code.gson:

gson:

+'

2.修改retrofit构建

ScalarsConverterFactory替换GsonConverterFactory

/*创建retrofit对象*/

Retrofitretrofit=newRetrofit.Builder()

.client(builder.build())

.addConverterFactory(ScalarsConverterFactory.create())

.addCallAdapterFactory(RxJavaCallAdapterFactory.create())

.baseUrl(basePar.getBaseUrl())

.build();

HttpServicehttpService=retrofit.create(HttpService.class);

替换

/*创建retrofit对象*/

Retrofitretrofit=newRetrofit.Builder()

.client(builder.build())

.addConverterFactory(GsonConverterFactory.create())

.addCallAdapterFactory(RxJavaCallAdapterFactory.create())

.baseUrl(basePar.getBaseUrl())

.build();

HttpServicehttpService=retrofit.create(HttpService.class);

3.修改缓存记录位置

由于之前是为了防止gson重复解析,将缓存放入到自定义CookieInterceptor中;既然现在不需要自动转换,直接返回String,所以直接将缓存数据处理放入到ProgressSubscriber的onNext中处理;

修改1:

去掉CookieInterceptor

//手动创建一个OkHttpClient并设置超时时间缓存等设置

OkHttpClient.Builderbuilder=newOkHttpClient.Builder();

builder.addInterceptor(newCacheInterceptor());

builder.addNetworkInterceptor(newCacheInterceptor());

替换

//手动创建一个OkHttpClient并设置超时时间缓存等设置

OkHttpClient.Builderbuilder=newOkHttpClient.Builder();

builder.addNetworkInterceptor(newCacheInterceptor());

builder.addInterceptor(newCookieInterceptor(basePar.isCache()));

修改二:

实现缓存处理

在onNext中实现缓存处理

/**

*将onNext方法中的返回结果交给Activity或Fragment自己处理

*

*@paramt创建Subscriber时的泛型类型

*/

@Override

publicvoidonNext(Tt){

/*缓存处理*/

if(api.isCache()){

CookieResulteresulte=CookieDbUtil.getInstance().queryCookieBy(api.getUrl());

longtime=System.currentTimeMillis();

/*保存和更新本地数据*/

if(resulte==null){

resulte=newCookieResulte(api.getUrl(),t.toString(),time);

CookieDbUtil.getInstance().saveCookie(resulte);

}else{

resulte.setResulte(t.toString());

resulte.setTime(ime);

CookieDbUtil.getInstance().updateCookie(resulte);

}

}

if(mSubscriberOnNextListener.get()!

=null){

mSubscriberOnNextListener.get().onNext((String)t,api.getMothed());

}

}

4.修改回调接口信息

由于现在通过String直接返回,所以可以将成功回调和缓存回调合并处理;另一方面没有了泛型的限制,在回调时可以通过接口请求参数实现一对多回调处理;

/**

*成功回调处理

*CreatedbyWZGon2016/7/16.

*/

publicinterfaceHttpOnNextListener{

/**

*成功后回调方法

*@paramresulte

*@parammethod

*/

voidonNext(Stringresulte,Stringmethod);

/**

*失败或者错误方法

*主动调用,更加灵活

*@parame

*/

voidonError(Throwablee);

}

5.修改BaseApi

由于取消了泛型返回的机制,所以在Func1判断时需要手动转换数据;这里示例fastjeson用法转换

@Override

publicStringcall(ThttpResult){

BaseResultEntitybaseResulte=JSONObject.parseObject(httpResult.toString(),BaseResultEntity.class);

if(baseResulte.getRet()==0){

thrownewHttpTimeException(baseResulte.getMsg());

}

returnbaseResulte.getData();

}

替换

@Override

publicTcall(BaseResultEntityhttpResult){

if(httpResult.getRet()==0){

thrownewHttpTimeException(httpResult.getMsg());

}

returnhttpResult.getData();

}

6.修改结果基础类BaseResultEntity

将泛型数据改成String数据类型

/**

*回调信息统一封装类

*CreatedbyWZGon2016/7/16.

*/

publicclassBaseResultEntity{

//判断标示

privateintret;

//提示信息

privateStringmsg;

//显示数据(用户需要关心的数据)

privateStringdata;

}

替换

/**

*回调信息统一封装类

*CreatedbyWZGon2016/7/16.

*/

publicclassBaseResultEntity{

//判断标示

privateintret;

//提示信息

privateStringmsg;

//显示数据(用户需要关心的数据)

privateTdata;

}

7.合并缓存和成功回到返回处理

由于取消泛型,缓存和成统一处理所以需要修改

/**

*订阅开始时调用

*显示ProgressDialog

*/

@Override

publicvoidonStart(){

showProgressDialog();

/*缓存并且有网*/

if(api.isCache()&&AppUtil.isNetworkAvailable(MyApplication.app)){

/*获取缓存数据*/

CookieResultecookieResulte=CookieDbUtil.getInstance().queryCookieBy(api.getUrl());

if(cookieResulte!

=null){

longtime=(System.currentTimeMillis()-cookieResulte.getTime())/1000;

if(time

if(mSubscriberOnNextListener.get()!

=null){

mSubscriberOnNextListener.get().onNext(cookieResulte.getResulte(),api.getMothed());

}

onCompleted();

unsubscribe();

}

}

}

}

替换

/**

*订阅开始时调用

*显示ProgressDialog

*/

@Override

publicvoidonStart(){

showProgressDialog();

/*缓存并且有网*/

if(api.isCache()&&AppUtil.isNetworkAvailable(MyApplication.app)){

/*获取缓存数据*/

CookieResultecookieResulte=CookieDbUtil.getInstance().queryCookieBy(api.getUrl());

if(cookieResulte!

=ull){

longtime=(System.currentTimeMillis()-cookieResulte.getTime())/1000;

if(time

if(mSubscriberOnNextListener.get()!

=null){

mSubscriberOnNextListener.get().onCacheNext(cookieResulte.getResulte());

}

onCompleted();

unsubscribe();

}

}

}

}

8.修改一对多回调处理

没有了泛型,可以修改HttpManager,采用动态创建,动态回调的方法解决多嵌套耦合的问题

修改1:

去掉默认构造传参

publicBaseApi(HttpOnNextListenerlistener,RxAppCompatActivityrxAppCompatActivity){

setListener(listener);

setRxAppCompatActivity(rxAppCompatActivity);

setShowProgress(true);

setCache(true);

}

修改2:

添加HttpManager动态传参

/**

*http交互处理类

*CreatedbyWZGon2016/7/16.

*/

publicclassHttpManager{

/*弱引用對象*/

privateSoftReferenceonNextListener;

privateSoftReferenceappCompatActivity;

publicHttpManager(HttpOnNextListeneronNextListener,RxAppCompatActivityappCompatActivity){

this.onNextListener=newSoftReference(onNextListener);

this.appCompatActivity=newSoftReference(appCompatActivity);

}

*******************

*******************

}

修改3:

通过method动态判断接口返回

publicclassMainActivityextendsRxAppCompatActivityimplementsHttpOnNextListener{

@Override

publicvoidonNext(Stringresulte,Stringmethod){

/*post返回处理*/

if(method.equals(postEntity.getMothed())){

*******

}

/*上传返回处理*/

if(method.equals(uplaodApi.getMothed())){

*********

}

}

@Override

publicvoidonError(Throwablee){

tvMsg.setText("失败:

\n"+e.toString());

}

}

大功告成!

下载模块

由于下载模块是独立存在,所以基本没有修改,唯一修改的地方就是将HttpDownManager中的GsonConverterFactory替换成ScalarsConverterFactory即可!

总结

通过自定义String类型的返回处理方式,有效的解决了之前Gson自动转换的问题

1.一对一返回问题(代码量多)

2.缓存回调无法和成功统一处理

3.无法指定gson转换第三方库

4.回调监听的多嵌套(耦合度大)

5.解决服务器数据null异常

注意:

这里只是给大家提供了一个不同的解决方案,Gson自动解析返回的方案也是有它的优点,可以大大的减少开发的工作量,优缺点也很明显;孰好孰坏自行判断,自行选择适合自己的方案(个人偏向后者String返回,比较灵活)

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 表格模板 > 合同协议

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1