浅谈RxJava+Retrofit+OkHttp 封装使用 之前发出后收到很多朋友的关注,原本只是自己学习后的一些经验总结,但是有同学运用到实战当中,这让我很惶恐,所有后续一直更新了很多次版本,有些地方难免有所变动导致之前的博客有所出入,正好最近受到掘金邀请内测博客,所以决定重新写一版,按照最后迭代完成的封装详细的讲述一遍,欢迎大家关注!
注意:由于本章的特殊性,后续文章比较长而且复杂,涉及内容也很多,所以大家准备好茶水,前方高能预警。
简介:
Retrofit: Retrofit是Square 公司开发的一款正对AndroID 网络请求的框架。底层基于Okhttp 实现,Okhttp 已经得到了Google 官方的认可。
Okhttp: 也是Square 开源的网络请求库
RxJava:RxJava 在 GitHub 主页上的自我介绍是 "a library for composing asynchronous and event-based programs using observable sequences for the Java VM"(一个在 Java VM 上使用可观测的序列来组成异步的、基于事件的程序的库)。这就是 RxJava ,概括得非常精准。总之就是让异步 *** 作变得非常简单。
各自的职责:Retrofit 负责请求的数据和请求的结果,使用接口的方式呈现,Okhttp 负责请求的过程,RxJava 负责异步,各种线程之间的切换。
RxJava + Retrofit + okhttp 已成为当前AndroID 网络请求最流行的方式。
封装成果
封装完以后,具有如下功能:
1.Retrofit+Rxjava+okhttp基本使用方法
2.统一处理请求数据格式
3.统一的ProgressDialog和回调Subscriber处理
4.取消http请求
5.预处理http请求
6.返回数据的统一判断
7.失败后的retry封装处理
8.Rxlifecycle管理生命周期,防止泄露
实现效果:
具体使用
封装后http请求代码如下
// 完美封装简化版 private voID simpleDo() { SubjectPost postEntity = new SubjectPost(simpleOnNextListener,this); postEntity.setAll(true); httpManager manager = httpManager.getInstance(); manager.dohttpDeal(postEntity); } // 回调一一对应 httpOnNextListener simpleOnNextListener = new httpOnNextListener<List<Subject>>() { @OverrIDe public voID onNext(List<Subject> subjects) { tvMsg.setText("已封装:\n" + subjects.toString()); } /*用户主动调用,默认是不需要覆写该方法*/ @OverrIDe public voID onError(Throwable e) { super.onError(e); tvMsg.setText("失败:\n" + e.toString()); } };
是不是很简单?你可能说这还简单,好咱们对比一下正常使用Retrofit的方法
/** * Retrofit加入rxjava实现http请求 */ private voID onbutton9Click() { //手动创建一个OkhttpClIEnt并设置超时时间 okhttp3.OkhttpClIEnt.Builder builder = new OkhttpClIEnt.Builder(); builder.connectTimeout(5,TimeUnit.SECONDS); Retrofit retrofit = new Retrofit.Builder() .clIEnt(builder.build()) .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .baseUrl(httpManager.BASE_URL) .build(); / 加载框 final ProgressDialog pd = new ProgressDialog(this); httpService APIService = retrofit.create(httpService.class); Observable<RetrofitEntity> observable = APIService.getAllVedioBy(true); observable.subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io()).observeOn(AndroIDSchedulers.mainThread()) .subscribe( new Subscriber<RetrofitEntity>() { @OverrIDe public voID onCompleted() { if (pd != null && pd.isShowing()) { pd.dismiss(); } } @OverrIDe public voID onError(Throwable e) { if (pd != null && pd.isShowing()) { pd.dismiss(); } } @OverrIDe public voID onNext(RetrofitEntity retrofitEntity) { tvMsg.setText("无封装:\n" + retrofitEntity.getData().toString()); } @OverrIDe public voID onStart() { super.onStart(); pd.show(); } } ); }
可能你发现确是代码有点多,但是更加可怕的是,如果你一个activity或者fragment中多次需要http请求,你需要多次重复的写回调处理(一个回到就有4个方法呀!!!!反正我是忍受不了),而且以上处理还没有做过多的判断和错误校验就如此复杂!~好了介绍完了,开始咱们的优化之路吧!
项目结构:
Retrofit
咱家今天的主角来了,咱们也深入浅出一下了解下Retrofit使用,前方高能,如果你是深度Retrofit选手请直接跳过本节!!!
1.首先确保在AndroIDManifest.xml中请求了网络权限
<uses-permission androID:name="androID.permission.INTERNET"/>
2.在app/build.gradle添加引用
/*rx-androID-java*/ compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0' compile 'com.trello:rxlifecycle:1.0' compile 'com.trello:rxlifecycle-components:1.0' /*rotrofit*/ compile 'com.squareup.retrofit2:retrofit:2.1.0' compile 'com.squareup.retrofit2:converter-gson:2.0.0' compile 'com.Google.code.gson:gson:2.8.0'
3.常用注解
这里介绍一些常用的注解的使用
@query、@queryMap:用于http Get请求传递参数 @FIEld:用于Post方式传递参数,需要在请求接口方法上添加@FormUrlEncoded,即以表单的方式传递参数 @Body:用于Post,根据转换方式将实例对象转化为对应字符串传递参数.比如Retrofit添加GsonConverterFactory则是将body转化为gson字符串进行传递 @Path:用于URL上占位符 @Part:配合@Multipart使用,一般用于文件上传 @header:添加http header @headers:跟@header作用一样,只是使用方式不一样,@header是作为请求方法的参数传入,@headers是以固定方式直接添加到请求方法上ReTrofit基本使用:
首先给定一个测试接口文档,后面的博客中我们都是用这个接口调试
/** * @API vIDeolink 50音图视频链接 * @url http://www.izaodao.com/API/AppFiftyToneGraph/vIDeolink * @method post * @param once_no bool(选填,ture无链接) 一次性获取下载地址 * @return Json array( * ret:1成功,2失败 * msg:信息 * data:{ * name:视频名称 * Title:标题 * } )
1.初始化retrofit
要向一个API发送我们的网络请求 ,我们需要使用Retrofit builder类并指定service的base URL(通常情况下就是域名)。
String BASE_URL = " http://www.izaodao.com/API/" Retrofit retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .build();
2.设置接口service
注意到每个endpoint 都指定了一个关于http(GET,POST,等等。) 方法的注解以及用于分发网络调用的方法。而且这些方法的参数也可以有特殊的注解。
/** * 接口地址 * Created by WZG on 2016/7/16. */ public interface MyAPIEndpointInterface { @POST("AppFiftyToneGraph/vIDeolink") Call<RetrofitEntity> getAllVedio(@Body boolean once_no) }
3.得到call然后同步处理处理回调:
MyAPIEndpointInterface APIService = retrofit.create(MyAPIEndpointInterface.class); Call<RetrofitEntity> call = APIService.getAllVedio(true); call.enqueue(new Callback<RetrofitEntity>() { @OverrIDe public voID onResponse(Response<RetrofitEntity> response,Retrofit retrofit) { RetrofitEntity entity = response.body(); Log.i("tag","onResponse----->" + entity.getMsg()); } @OverrIDe public voID onFailure(Throwable t) { Log.i("tag","onFailure----->" + t.toString()); } });
这就是简单的Retrofit使用步骤,接下来我们结合RxJava讲述
ReTrofit+Rxjava基本使用
对比之前的Retrofit使用
1.在于我们需要修改service接口返回信息我们需要返回一个Observable对象
@POST("AppFiftyToneGraph/vIDeolink") Observable<RetrofitEntity> getAllVedioBy(@Body boolean once_no);
2.然后初始化Retrofit需要添加对Rxjava的适配,注意一定要retrofit2才有这个功能哦
Retrofit retrofit = new Retrofit.Builder() .clIEnt(builder.build()) .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .baseUrl(httpManager.BASE_URL) .build();
3.回调通过RxJava处理
httpService APIService = retrofit.create(httpService.class); Observable<RetrofitEntity> observable = APIService.getAllVedioBy(true); observable.subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io()).observeOn(AndroIDSchedulers.mainThread()) .subscribe( new Subscriber<RetrofitEntity>() { @OverrIDe public voID onCompleted() { } @OverrIDe public voID onError(Throwable e) { } @OverrIDe public voID onNext(RetrofitEntity retrofitEntity) { tvMsg.setText("无封装:\n" + retrofitEntity.getData().toString()); } } );
简单的RxJava集合Retrofit的使用就介绍完了,同样的可以发现使用起来很多重复性的代码,而且使用也不是那么简单,所以才有了下面的封装
ReTrofit+Rxjava进阶封装之路
先来一张流程图压压惊
请求数据封装
1.参数
首先需要封装的使我们的数据类,在数据类中需要封装请求中用到的相关数据的设置,比如请求参数、方法、加载框显示设置等等
public abstract class BaseAPI<T> implements Func1<BaseResultEntity<T>,T> { //rx生命周期管理 private SoftReference<RxAppCompatActivity> rxAppCompatActivity; /*回调*/ private SoftReference<httpOnNextListener> Listener; /*是否能取消加载框*/ private boolean cancel; /*是否显示加载框*/ private boolean showProgress; /*是否需要缓存处理*/ private boolean cache; /*基础url*/ private String baseUrl="http://www.izaodao.com/API/"; /*方法-如果需要缓存必须设置这个参数;不需要不用O置*/ private String mothed; /*超时时间-默认6秒*/ private int connectionTime = 6; /*有网情况下的本地缓存时间默认60秒*/ private int cookieNetWorkTime=60; /*无网络的情况下本地缓存时间默认30天*/ private int cookieNoNetWorkTime=24*60*60*30;}
注释很详细,这里不具体描述了,由于这里是最后封装完成以后的代码,所以有些内容本章还会部分不会涉及,因为功能太多,还是按照一开始的博客章节讲解。
2.抽象API接口
/** * 设置参数 * * @param retrofit * @return */ public abstract Observable getobservable(Retrofit retrofit);
通过子类也即是我们的具体API接口,通过getobservable实现service中定义的接口方法,例如:
public class SubjectPostAPI extends BaseAPI { xxxxxxx xxxxxxx @OverrIDe public Observable getobservable(Retrofit retrofit) { httppostservice service = retrofit.create(httppostservice.class); return service.getAllVedioBys(isAll()); }}
通过传入的Retrofit对象,可以随意切换挑选Service对象,得到定义的注解方法,初始完成以后返回Observable对象。
3.结果判断
这里结合RxJava的map方法在服务器返回数据中,统一处理数据处理,所以BaseAPI<T> implements
Func1<BaseResultEntity<T>,T>,后边结合结果处理链接起来使用 @OverrIDe public T call(BaseResultEntity<T> httpResult) { if (httpResult.getRet() == 0) { throw new httpTimeException(httpResult.getMsg()); } return httpResult.getData(); }
由于测试接口,也是当前我们公司接口都是有统一规则的,想必大家都有这样的接口规则,所以才有这里的统一判断,规则如下:
* ret:1成功,2失败 * msg:信息 * data:{ * name:视频名称 * Title:标题 * }
其实上面的接口文档中就介绍了,统一先通过ret判断,失败显示msg信息,data是成功后的数据也就是用户关心的数据,所以可封装一个结果对象BaseResultEntity.
4.结果数据
/** * 回调信息统一封装类 * Created by WZG on 2016/7/16. */public class BaseResultEntity<T> { // 判断标示 private int ret; // 提示信息 private String msg; //显示数据(用户需要关心的数据) private T data; xxxxx get-set xxxxx}
这里结合BaseAPI的Func1判断,失败直接抛出一个异常,交个RxJava的onError处理,成功则将用户关心的数据传给Gson解析返回
5.泛型传递
BaseResultEntity<T>中的泛型T也就是我们所关心的回调数据,同样也是Gson最后解析返回的数据,传递的过程根节点是通过定义service方法是给定的,例如:
public interface httppostservice { @POST("AppFiftyToneGraph/vIDeolink") Call<RetrofitEntity> getAllVedio(@Body boolean once_no);}
其中的RetrofitEntity就是用户关心的数据类,通过泛型传递给最后的接口。
6.强调
很多兄弟通过QQ群反馈给我说,使用一个接口需要写一个对应的API类继承BaseAPI是不是很麻烦,我这里强调一下,这样封装是为了将一个API接口作为一个对象去封装,个人觉得有必要封装成一个类,在日后工程日益增加接口随着增加的同时,对象的做法更加有利于查找接口和修改接口有利于迭代。
*** 作类封装
1初始对象
首先初始化一个单利方便httpManager请求;这里用了volatile的对象
private volatile static httpManager INSTANCE; //构造方法私有 private httpManager() { } //获取单例 public static httpManager getInstance() { if (INSTANCE == null) { synchronized (httpManager.class) { if (INSTANCE == null) { INSTANCE = new httpManager(); } } } return INSTANCE; }
2接口处理和回调处理:
/** * 处理http请求 * * @param basePar 封装的请求数据 */ public voID dohttpDeal(BaseAPI basePar) { //手动创建一个OkhttpClIEnt并设置超时时间缓存等设置 OkhttpClIEnt.Builder builder = new OkhttpClIEnt.Builder(); builder.connectTimeout(basePar.getConnectionTime(),TimeUnit.SECONDS); builder.addInterceptor(new cookieInterceptor(basePar.isCache())); /*创建retrofit对象*/ Retrofit retrofit = new Retrofit.Builder() .clIEnt(builder.build()) .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .baseUrl(basePar.getBaseUrl()) .build(); /*rx处理*/ ProgressSubscriber subscriber = new ProgressSubscriber(basePar); Observable observable = basePar.getobservable(retrofit) /*失败后的retry配置*/ .retrywhen(new retrywhenNetworkException()) /*生命周期管理*/ .compose(basePar.getRxAppCompatActivity().bindTolifecycle()) /*http请求线程*/ .subscribeOn(Schedulers.io()) .unsubscribeOn(Schedulers.io()) /*回调线程*/ .observeOn(AndroIDSchedulers.mainThread()) /*结果判断*/ .map(basePar); /*数据回调*/ observable.subscribe(subscriber); }
首先通过API接口类BaseAPI的实现类中数据初始化OkhttpClIEnt和Retrofit对象,其中包含了url,超时等,接着通过BaseAPI的抽象方法getobservable得到Observable对象,得到Observable对象以后,我们就能随意的切换现成来处理,整个请求通过compose设定的rxlifecycle来管理生命周期,所以不会溢出和泄露无需任何担心,最后再服务器数据返回时,通过map判断结果,剔除错误信息,成功以后返回到自定义的ProgressSubscriber对象中,所以接下来封装ProgressSubscriber对象。
ProgressSubscriber封装
ProgressSubscriber其实是继承于Subscriber,封装的方法无非是对Subscriber的回调方法的封装
onStart():开始 onCompleted():结束 onError(Throwable e):错误 onNext(T t):成功1.请求加载框
http请求都伴随着加载框的使用,所以这里需要在onStart()使用前初始一个加载框,这里简单的用ProgressDialog代替
/** * 用于在http请求开始时,自动显示一个ProgressDialog * 在http请求结束是,关闭ProgressDialog * 调用者自己对请求数据进行处理 * Created by WZG on 2016/7/16. */public class ProgressSubscriber<T> extends Subscriber<T> { /*是否d框*/ private boolean showPorgress = true; /* 软引用回调接口*/ private SoftReference<httpOnNextListener> mSubscriberOnNextListener; /*软引用反正内存泄露*/ private SoftReference<RxAppCompatActivity> mActivity; /*加载框可自己定义*/ private ProgressDialog pd; /*请求数据*/ private BaseAPI API; /** * 构造 * * @param API */ public ProgressSubscriber(BaseAPI API) { this.API = API; this.mSubscriberOnNextListener = API.getListener(); this.mActivity = new SoftReference<>(API.getRxAppCompatActivity()); setShowPorgress(API.isShowProgress()); if (API.isShowProgress()) { initProgressDialog(API.isCancel()); } } /** * 初始化加载框 */ private voID initProgressDialog(boolean cancel) { Context context = mActivity.get(); if (pd == null && context != null) { pd = new ProgressDialog(context); pd.setCancelable(cancel); if (cancel) { pd.setonCancelListener(new DialogInterface.OnCancelListener() { @OverrIDe public voID onCancel(DialogInterface dialogInterface) { onCancelProgress(); } }); } } } /** * 显示加载框 */ private voID showProgressDialog() { if (!isShowPorgress()) return; Context context = mActivity.get(); if (pd == null || context == null) return; if (!pd.isShowing()) { pd.show(); } } /** * 隐藏 */ private voID dismissprogressDialog() { if (!isShowPorgress()) return; if (pd != null && pd.isShowing()) { pd.dismiss(); } }}
由于progress的特殊性,需要指定content而且不能是Application所以这里传递一个RxAppCompatActivity,而同时上面的httpManager同样需要,所以这里统一还是按照BaseAPI传递过来,使用软引用的方式避免泄露。剩下的无非是初始化,显示和关闭方法,可以详细看代码。
2.onStart()实现
在onStart()中需要调用加载框,然后这里还有网络缓存的逻辑,后面会单独讲解,现在先忽略它的存在。
/** * 订阅开始时调用 * 显示ProgressDialog */ @OverrIDe public voID onStart() { showProgressDialog(); /*缓存并且有网*/ if (API.isCache() && AppUtil.isNetworkAvailable(RxRetrofitApp.getApplication())) { /*获取缓存数据*/ cookieResulte cookieResulte = cookieDbUtil.getInstance().querycookieBy(API.getUrl()); if (cookieResulte != null) { long time = (System.currentTimeMillis() - cookieResulte.getTime()) / 1000; if (time < API.getcookieNetWorkTime()) { if (mSubscriberOnNextListener.get() != null) { mSubscriberOnNextListener.get().onCacheNext(cookieResulte.getResulte()); } onCompleted(); unsubscribe(); } } } }
3.onCompleted()实现
/** * 完成,隐藏ProgressDialog */ @OverrIDe public voID onCompleted() { dismissprogressDialog(); }
4.onError(Throwable e)实现
在onError(Throwable e)是对错误信息的处理和缓存读取的处理,后续会讲解,先忽略。
/** * 对错误进行统一处理 * 隐藏ProgressDialog * * @param e */ @OverrIDe public voID onError(Throwable e) { dismissprogressDialog(); /*需要娌⑶冶镜赜谢捍娌欧祷*/ if (API.isCache()) { Observable.just(API.getUrl()).subscribe(new Subscriber<String>() { @OverrIDe public voID onCompleted() { } @OverrIDe public voID onError(Throwable e) { errorDo(e); } @OverrIDe public voID onNext(String s) { /*获取缓存数据*/ cookieResulte cookieResulte = cookieDbUtil.getInstance().querycookieBy(s); if (cookieResulte == null) { throw new httpTimeException("网络错误"); } long time = (System.currentTimeMillis() - cookieResulte.getTime()) / 1000; if (time < API.getcookieNoNetWorkTime()) { if (mSubscriberOnNextListener.get() != null) { mSubscriberOnNextListener.get().onCacheNext(cookieResulte.getResulte()); } } else { cookieDbUtil.getInstance().deletecookie(cookieResulte); throw new httpTimeException("网络错误"); } } }); } else { errorDo(e); } } /*错误统一处理*/ private voID errorDo(Throwable e) { Context context = mActivity.get(); if (context == null) return; if (e instanceof SocketTimeoutException) { Toast.makeText(context,"网络中断,请检查您的网络状态",Toast.LENGTH_SHORT).show(); } else if (e instanceof ConnectException) { Toast.makeText(context,Toast.LENGTH_SHORT).show(); } else { Toast.makeText(context,"错误" + e.getMessage(),Toast.LENGTH_SHORT).show(); } if (mSubscriberOnNextListener.get() != null) { mSubscriberOnNextListener.get().onError(e); } }
5.onNext(T t)实现
/** * 将onNext方法中的返回结果交给Activity或Fragment自己处理 * * @param t 创建Subscriber时的泛型类型 */ @OverrIDe public voID onNext(T t) { if (mSubscriberOnNextListener.get() != null) { mSubscriberOnNextListener.get().onNext(t); } }
主要是是将得到的结果,通过自定义的接口返回给vIEw界面,其中的软引用对象mSubscriberOnNextListener是自定义的接口回调类httpOnNextListener.
6.httpOnNextListener封装
现在只需关心onNext(T t)和onError(Throwable e)接口即可,回调的触发点都是在上面的ProgressSubscriber中调用
/** * 成功回调处理 * Created by WZG on 2016/7/16. */public abstract class httpOnNextListener<T> { /** * 成功后回调方法 * @param t */ public abstract voID onNext(T t); /** * 婊卣{Y果 * @param string */ public voID onCacheNext(String string){ } /** * 失败或者错误方法 * 主动调用,更加灵活 * @param e */ public voID onError(Throwable e){ } /** * 取消回{ */ public voID onCancel(){ }}
失败后的retry处理
这里你可能会问,Retrofit有自带的retry处理呀,的确Retrofit有自带的retry处理,但是有很多的局限,先看下使用
OkhttpClIEnt.Builder builder = new OkhttpClIEnt.Builder();builder.retryOnConnectionFailure(true);
使用起来还是很方便,只需要调用一个方法即可,但是它是不可控的,也就是没有办法设置retry时间次数,所以不太灵活,既然如此还不如自己封装一下,因为用RxJava实现这个简直小菜,无形中好像已经给RxJava打了广告,中毒太深。
很简单直接上代码:
/** * retry条件 * Created by WZG on 2016/10/17. */public class retrywhenNetworkException implements Func1<Observable<? extends Throwable>,Observable<?>> {// retry次数 private int count = 3;// 延迟 private long delay = 3000;// 叠加延迟 private long increaseDelay = 3000; public retrywhenNetworkException() { } public retrywhenNetworkException(int count,long delay) { this.count = count; this.delay = delay; } public retrywhenNetworkException(int count,long delay,long increaseDelay) { this.count = count; this.delay = delay; this.increaseDelay = increaseDelay; } @OverrIDe public Observable<?> call(Observable<? extends Throwable> observable) { return observable .zipwith(Observable.range(1,count + 1),new Func2<Throwable,Integer,Wrapper>() { @OverrIDe public Wrapper call(Throwable throwable,Integer integer) { return new Wrapper(throwable,integer); } }).flatMap(new Func1<Wrapper,Observable<?>>() { @OverrIDe public Observable<?> call(Wrapper wrapper) { if ((wrapper.throwable instanceof ConnectException || wrapper.throwable instanceof SocketTimeoutException || wrapper.throwable instanceof TimeoutException) && wrapper.index < count + 1) { //如果超出重试次数也抛出错误,否则默认是会进入onCompleted return Observable.timer(delay + (wrapper.index - 1) * increaseDelay,TimeUnit.MILliSECONDS); } return Observable.error(wrapper.throwable); } }); } private class Wrapper { private int index; private Throwable throwable; public Wrapper(Throwable throwable,int index) { this.index = index; this.throwable = throwable; } }}
使用
到这里,我们第一步封装已经完成了,下面讲解下如何使用,已经看明白的各位看官,估计早就看明白了使用方式,无非是创建一个API对象继承BaseAPI初始接口信息,然后调用httpManager对象的dohttpDeal(BaseAPI basePar)方法,最后静静的等待回调类httpOnNextListener<T>类返回的onNext(T t)成功数据或者onError(Throwable e)数据。
其实代码就是这样:
API接口对象
/** * 测试数据 * Created by WZG on 2016/7/16. */public class SubjectPostAPI extends BaseAPI {// 接口需要传入的参数 可自定义不同类型 private boolean all; /*任何你先要传递的参数*/// String xxxxx; /** * 默认初始化需要给定回调和rx周期类 * 可以额外设置请求设置加载框显示,回调等(可扩展) * @param Listener * @param rxAppCompatActivity */ public SubjectPostAPI(httpOnNextListener Listener,RxAppCompatActivity rxAppCompatActivity) { super(Listener,rxAppCompatActivity); setShowProgress(true); setCancel(true); setCache(true); setMothed("AppFiftyToneGraph/vIDeolink"); setcookieNetWorkTime(60); setcookieNoNetWorkTime(24*60*60); } public boolean isAll() { return all; } public voID setAll(boolean all) { this.all = all; } @OverrIDe public Observable getobservable(Retrofit retrofit) { httppostservice service = retrofit.create(httppostservice.class); return service.getAllVedioBys(isAll()); }}
请求回调
// 完美封装简化版 private voID simpleDo() { SubjectPostAPI postEntity = new SubjectPostAPI(simpleOnNextListener,this); postEntity.setAll(true); httpManager manager = httpManager.getInstance(); manager.dohttpDeal(postEntity); } // 回调一一对应 httpOnNextListener simpleOnNextListener = new httpOnNextListener<List<SubjectResulte>>() { @OverrIDe public voID onNext(List<SubjectResulte> subjects) { tvMsg.setText("网络返回:\n" + subjects.toString()); } @OverrIDe public voID onCacheNext(String cache) { /*缓存回调*/ Gson gson=new Gson(); java.lang.reflect.Type type = new Typetoken<BaseResultEntity<List<SubjectResulte>>>() {}.getType(); BaseResultEntity resultEntity= gson.fromJson(cache,type); tvMsg.setText("缓存返回:\n"+resultEntity.getData().toString() ); } /*用户主动调用,默认是不需要覆写该方法*/ @OverrIDe public voID onError(Throwable e) { super.onError(e); tvMsg.setText("失败:\n" + e.toString()); } /*用户主动调用,默认是不需要覆写该方法*/ @OverrIDe public voID onCancel() { super.onCancel(); tvMsg.setText("取消求"); } };
后续
到这里,封装功能中很多功能还没涉及和讲解,后续会陆续更新!
先给大家看看为师的完全体功能:
1.Retrofit+Rxjava+okhttp基本使用方法
2.统一处理请求数据格式
3.统一的ProgressDialog和回调Subscriber处理
4.取消http请求
5.预处理http请求
6.返回数据的统一判断
7.失败后的retry处理
8.Rxlifecycle管理生命周期,防止泄露
9.文件上传下载(支持多文件,断点续传)
10.Cache数据持久化和数据库(greenDao)两种缓存机制
11.异常统一处理
来个图压压惊:
源码:
RxRetrofit-终极封装-深入浅出&网络请求-GitHub
其实我还有一个兄弟版本-传送门
我不会告诉你其实我还有个更加简单的版本
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。
以上是内存溢出为你收集整理的深入浅出RxJava+Retrofit+OkHttp网络请求全部内容,希望文章能够帮你解决深入浅出RxJava+Retrofit+OkHttp网络请求所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)