以前在github开源过一个网络库RxEasyHttp,这是一款基于RxJava2+Retrofit2实现简单易用的网络请求框架。在这里对网络库的用法就不作过多介绍,感兴趣的能够去了解下。在使用过程当中一些网友反馈不知道怎么结合Rxjava2来实现一些场景需求,但愿可以写一遍文章介绍下。终于抽出时间来对与Rxjava2在实际场景使用的一些案例作个简单的总结和介绍。不知道怎么使用,主要是对RxEasyHttp有个误区,RxEasyHttp不只是支持采用链式调用一点到底方便使用,同时也支持返回Observable
的用法,拿到了Observable
天然就能够很好的利用Rxjava操做符了来实现各类强大的功能。本文主要是讲RxEasyHttp与Rxjava2怎么结合的,也不会Rxjava2的操做符深刻讲解,否则就脱离了本文的重心!废话很少说了,一块儿来看看是如何使用的。php
在页面网络接口请求中,不是但愿立马请求,而是须要延迟指定的时间后再去请求。
延迟请求:利用RxJava的timer
操做符。
timer:主要做用就是建立一个Observable
,它在一个给定的延迟后发射一个特殊的值,只是延迟发送一次并不会按照周期执行。timer()
源码以下:java
public static Observable<Long> timer(long delay, TimeUnit unit) { return timer(delay, unit, Schedulers.computation()); }
能够看到采用timer()
返回的是Observable<Long>
,而网络请求返回的Observable
并非Observable<Long>
,如何将这两个Observable
关联起来,就须要采用另一个操做符flatMap()
,简单理解就是flatMap
使用一个指定的函数对原始Observable发射的每一项数据进行相应的变换操做。flatMap详细做用不作过多介绍。
例如:延迟5秒请求git
//延迟5s请求 Observable.timer(5, TimeUnit.SECONDS).flatMap(new Function<Long, ObservableSource<SkinTestResult>>() { @Override public ObservableSource<SkinTestResult> apply(@NonNull Long aLong) throws Exception { //延迟结束开始执行网络请求 Observable<SkinTestResult> observable = EasyHttp.get("/v1/app/chairdressing/skinAnalyzePower/skinTestResult") .timeStamp(true) .execute(SkinTestResult.class); return observable; } }).subscribe(new BaseSubscriber<SkinTestResult>() { @Override protected void onStart() { } @Override public void onError(ApiException e) { showToast(e.getMessage()); } @Override public void onNext(@NonNull SkinTestResult skinTestResult) { Log.i("test", "=====" + skinTestResult.toString()); } }); //在不须要轮询的时候,取消轮询 //EasyHttp.cancelSubscription(polldisposable);
- timer在这里做用延迟5s结束时就会触发网络请求
- flatMap在这里的做用就是将
timer
操做符返回的Observable<Long>
和网络请求的Observable<SkinTestResult>
作转换,在subscribe订阅时返回的内容,咱们真正须要的SkinTestResult,而不是Long. 所以将Observable<Long>
变换成Observable<SkinTestResult>
输出SkinTestResult,完美达到目的。
在项目中须要用到每隔5s刷新一次页面或者拉取最新消息。轮询器你们必定不陌生,开发中不管是Java的Timer+TimeTask , 仍是Android的Hanlder均可实现,如今介绍另外一种简单的实现方式。
无限轮询:利用RxJava的Interval
操做符。
interval:建立一个按固定时间间隔发射整数序列的Observable,它是按照周期执行的。源码以下(只展现相关的两个方法):github
public static Observable<Long> interval(long initialDelay, long period, TimeUnit unit) { return interval(initialDelay, period, unit, Schedulers.computation()); } public static Observable<Long> interval(long period, TimeUnit unit) { return interval(period, period, unit, Schedulers.computation()); }
能够看到采用interval()
返回的是Observable<Long>
,而网络请求返回的Observable
并非Observable<Long>
,如何将这两个Observable
关联起来,就须要采用另一个操做符flatMap()
,简单理解就是flatMap使用一个指定的函数对原始Observable发射的每一项数据之行相应的变换操做。flatMap详细做用不作过多介绍(同上场景一)。
例如:间隔5s轮询一次ajax
//本身根据须要选择合适的interval方法 Disposable polldisposable = Observable.interval(0, 5, TimeUnit.SECONDS).flatMap(new Function<Long, ObservableSource<Content>>() { @Override public ObservableSource<Content> apply(@NonNull Long aLong) throws Exception { return EasyHttp.get("/ajax.php") .baseUrl("http://fy.iciba.com") .params("a", "fy") .params("f", "auto") .params("t", "auto") .params("w", "hello world") //采用代理 .execute(new CallClazzProxy<TestApiResult6<Content>, Content>(Content.class) { }); } }).subscribeWith(new BaseSubscriber<Content>() { @Override public void onError(ApiException e) { showToast(e.getMessage()); } @Override public void onNext(@NonNull Content content) { showToast(content.toString()); } }); //在不须要轮询的时候,取消轮询 //EasyHttp.cancelSubscription(polldisposable);
- interval在这里做用每隔5s结束时就会触发网络请求
- 注意
interval(0, 5, TimeUnit.SECONDS)
和interval(5, TimeUnit.SECONDS)
的区别,本身根据须要选择合适的interval方法。
interval(0,5, TimeUnit.SECONDS)
:3个参数,第一个参数表示初始化延时多久开始请求,这里用0表示不延时直接请求,第二个参数表示间隔多久轮询一次,这里表示间隔5s,第三个表示设置的时间单位。interval(5, TimeUnit.SECONDS)
:2个参数,其中的这个5就表示,初始延时5秒开始执行请求,轮询也是5s,第二个表示设置的时间单位,从上面提供的interval()
源码能够看出。json
flatMap
在这里的做用就是将interval
的Observable<Long>
和网络请求的Observable<Content>
作转换,输出Content,而不是Long.
这个和无限轮询用法基本同样,只是多了轮询的次数限制条件,不是一直无限的轮询下去。
轮询次数:利用RxJava的intervalRange
或者take
操做符。
intervalRange:以一个例子说明可能更清楚,intervalRange(0,3,0,5, TimeUnit.SECONDS)
表示从0开始输出3个数据,延迟0秒执行,每隔5秒执行一次。
take:表示只取前n项。这里用take和interval操做符联合使用,因为一旦interval计时开始除了解绑就没法中止,使用take操做符就简单不少了,它的意思是只释放前n项,事后Observable流就自动终止。
例如:只轮询3次api
int count = 3;//轮询3次 //方式一:采用intervalRange //Observable.intervalRange(0,count,0,5, TimeUnit.SECONDS).flatMap(new Function<Long, ObservableSource<Content>>() { //方式一:采用take countdisposable = Observable.interval(0, 5, TimeUnit.SECONDS).take(count).flatMap(new Function<Long, ObservableSource<Content>>() { @Override public ObservableSource<Content> apply(@NonNull Long aLong) throws Exception { return EasyHttp.get("/ajax.php") .baseUrl("http://fy.iciba.com") .params("a", "fy") .params("f", "auto") .params("t", "auto") .params("w", "hello world") //采用代理 .execute(new CallClazzProxy<TestApiResult6<Content>, Content>(Content.class) { }); } }).subscribeWith(new BaseSubscriber<Content>() { @Override public void onError(ApiException e) { showToast(e.getMessage()); } @Override public void onNext(@NonNull Content content) { showToast(content.toString()); } }); //在不须要轮询的时候,取消轮询 //EasyHttp.cancelSubscription(polldisposable);
条件轮询和限定次数轮询比较像,都是起达到目的后终止轮询。好比一个网络请求一直在轮询执行,直到获取到了想要的内容后就终止掉轮询。
条件轮询:利用RxJava的takeUntil
操做符。
takeUntil:使用一个标志Observable是否发射数据来判断,当标志Observable没有发射数据时,正常发射数据,而一旦标志Observable发射过了数据则后面的数据都会被丢弃。
例如:轮询请求中若是返回的内容字符串中包含“示”就终止轮询数组
Observable.interval(0, 5, TimeUnit.SECONDS).flatMap(new Function<Long, ObservableSource<Content>>() { @Override public ObservableSource<Content> apply(@NonNull Long aLong) throws Exception { return EasyHttp.get("/ajax.php") .baseUrl("http://fy.iciba.com") .params("a", "fy") .params("f", "auto") .params("t", "auto") .params("w", "hello world") //采用代理 .execute(new CallClazzProxy<TestApiResult6<Content>, Content>(Content.class) { }); } }).takeUntil(new Predicate<Content>() { @Override public boolean test(@NonNull Content content) throws Exception { //若是条件知足,就会终止轮询,这里逻辑能够本身写 //结果为true,说明知足条件了,就不在轮询了 return content.getOut().contains("示"); } }).subscribeWith(new BaseSubscriber<Content>() { @Override public void onError(ApiException e) { showToast(e.getMessage()); } @Override public void onNext(@NonNull Content content) { showToast(content.toString()); } }); //在不须要轮询的时候,取消轮询 //EasyHttp.cancelSubscription(polldisposable);
过滤轮询主要是指在轮询的过程当中对订阅的内容作过滤,不是须要的内容就不会返回给订阅者,可是它不会中断轮询。过滤轮询也能够理解成是无限轮询加了一个过滤条件而已。
过滤轮询:利用Rxjava的filter
操做符。
filter:是对源Observable产生的结果按照指定条件进行过滤,只有知足条件的结果才会提交给订阅者。
例如:返回的状态码若是是错误就不返回给订阅者,不更新界面(只有保证每次请求成功才刷新界面),可是会继续轮询请求缓存
Disposable filterdisposable = Observable.interval(0, 5, TimeUnit.SECONDS).flatMap(new Function<Long, ObservableSource<Content>>() { @Override public ObservableSource<Content> apply(@NonNull Long aLong) throws Exception { return EasyHttp.get("/ajax.php") .baseUrl("http://fy.iciba.com") .params("a", "fy") .params("f", "auto") .params("t", "auto") .params("w", "hello world") //采用代理 .execute(new CallClazzProxy<TestApiResult6<Content>, Content>(Content.class) { }); } }).filter(new Predicate<Content>() { @Override public boolean test(@NonNull Content content) throws Exception { //若是不知足条件就过滤该条轮询数据,可是轮询仍是一直执行 //ErrNo==0表示成功,若是不等于0就认为失败,content不会返回给订阅者 return content.getErrNo() != 0; } }).subscribeWith(new BaseSubscriber<Content>() { @Override public void onError(ApiException e) { showToast(e.getMessage()); } @Override public void onNext(@NonNull Content content) { showToast(content.toString()); } }); //在不须要轮询的时候,取消轮询 //EasyHttp.cancelSubscription(polldisposable);
filter
操做符在这里只是为了举列说明,是本身为了讲解定义了一个过滤轮询的概念,不是说filter
只能在轮询这里使用,它是能够和其它任何Rxjava操做符配合使用。- 切记
takeUntil
和filter
的区别,takeUntil
找到本身想要的数据后就结束了流,再也不执行任何操做。filter
发现不符合条件的不会给订阅者,只有符合条件的才给订阅者,发现不符合的,不会中断操做。
在开发中因为请求网络数据频繁,每每后面一个请求的参数是前面一个请求的结果,因而常常须要在前面一个请求的响应中去发送第二个请求,从而形成“请求嵌套”的问题。若是层次比较多,代码可读性和效率都是问题。嵌套请求:利用RxJava的flatMap
操做符。
flatMap:是一个Observable的操做符,接受一个Func1闭包,这个闭包的第一个函数是待操做的上一个数据流中的数据类型,第二个是这个flatMap操做完成后返回的数据类型的被封装的Observable。说白了就是将一个多级数列“拍扁”成了一个一级数列。
例如:网络请求获取到token后,把token当成另外一个接口的参数,一个接口依赖另外一个接口。网络
//第一个网络请求获取到token Observable<AuthModel> login = EasyHttp.post(ComParamContact.Login.PATH) .params(ComParamContact.Login.ACCOUNT, "186****4275") .params(ComParamContact.Login.PASSWORD, MD5.encrypt4login("123456", AppConstant.APP_SECRET)) .sign(true) .timeStamp(true).execute(AuthModel.class); login.flatMap(new Function<AuthModel, ObservableSource<SkinTestResult>>() { @Override public ObservableSource<SkinTestResult> apply(@NonNull AuthModel authModel) throws Exception { //获取到的token,给到第二个网络当参数。第二个网络开始请求 return EasyHttp.get("/v1/app/chairdressing/skinAnalyzePower/skinTestResult") .params("accessToken", authModel.getAccessToken())//这个地方只是举例,并不必定是须要accessToken .timeStamp(true) .execute(SkinTestResult.class); } }).subscribe(new ProgressSubscriber<SkinTestResult>(this, mProgressDialog) { @Override public void onError(ApiException e) { super.onError(e); showToast(e.getMessage()); } @Override public void onNext(SkinTestResult skinTestResult) { showToast(skinTestResult.toString()); } });
本例中只是展现了2个接口的嵌套请求,flatMap实际上是能够支持嵌套不少个接口请求
zip合并请求就是指当一个页面有多个不一样的数据来源,既就是有多个不一样的网络请求接口,等待这些全部的接口都请求完成后才返回给订阅者,刷新界面等操做。
zip:使用一个函数组合多个Observable发射的数据集合,而后再发射这个结果.
例如:一个页面有3个不一样数据来源的网络请求接口,等待所有请求完成后才返回
Observable<ResultBean> mobileObservable = EasyHttp.get("http://apis.juhe.cn/mobile/get") .params("phone", "18688994275") .params("dtype", "json") .params("key", "5682c1f44a7f486e40f9720d6c97ffe4") .execute(new CallClazzProxy<TestApiResult1<ResultBean>, ResultBean>(ResultBean.class) { }); Observable<Content> searchObservable = EasyHttp.get("/ajax.php") .baseUrl("http://fy.iciba.com") .params("a", "fy") .params("f", "auto") .params("t", "auto") .params("w", "hello world") //采用代理 .execute(new CallClazzProxy<TestApiResult6<Content>, Content>(Content.class) { }); Observable<List<SectionItem>> listObservable = EasyHttp.get("http://news-at.zhihu.com/api/3/sections") .execute(new CallClazzProxy<TestApiResult5<List<SectionItem>>, List<SectionItem>>(new TypeToken<List<SectionItem>>() { }.getType()) { }); //new Function3最后一个参数这里用的是List<Object>,表示将3个返回的结果,放在同一个集合最终一次性返回, 你也能够指定返回其它你须要的数据类型 并不必定是List<Object> //假如这三个接口返回的都是TestBean,那么就能够直接用具体的List<TestBean>,不须要用List<Object> Observable.zip(mobileObservable, searchObservable, listObservable, new Function3<ResultBean, Content, List<SectionItem>, List<Object>>() { @Override public List<Object> apply(@NonNull ResultBean resultbean, @NonNull Content content, @NonNull List<SectionItem> sectionItems) throws Exception { //将接收到的3个数据先暂存起来,一次性发给订阅者 List list = new ArrayList(); list.add(resultbean); list.add(content); list.add(sectionItems); //这里也能够进行逻辑处理,处理成你本身须要的结果后,再返回。 return list; } }).subscribe(new BaseSubscriber<List<Object>>() { @Override public void onError(ApiException e) { showToast(e.getMessage()); } @Override public void onNext(@NonNull List<Object> objects) { showToast(objects.toString()); } });
1.zip的参数中前几个参数都表示数据源ObservableSource
,最后一个参数new Function会输出结果,前面若是有2个数据源就用Function2,3个数据源就用Function3.
2.Function的做用主要是会返回全部参与zip的结果内容,例如本例是有3个数据源(3个网络接口请求对应的Observable),返回的内容是new Function3<ResultBean, Content, List<SectionItem>, List<Object>>
其中ResultBean, Content, List<SectionItem>
是三个网络接口各自返回的内容。可是最后一个参数List<Object>
表示什么呢?这一个就表示最终要给订阅着subscribe
的内容,例如本例new BaseSubscriber<List<Object>>()
。这里我是将返回的结果用一个List集合存起来,而后返回给订阅者。最终想返回什么是根据本身的业务逻辑需求而定,并不必定就是List<Object>
,切记!切记!切记!
刚才讲解了zip合并请求,这是合并请求的另外一种场景实现方式merge,必定要注意merge和zip的区别,虽然都是合并多个请求,可是是有区别的,请注意使用场景. 本例中利用Rxjava的merge
、mergeDelayError
操做符。
merge:将多个Observalbe发射的数据项,合并到一个Observable中再发射出去,可能会让合并的Observable发射的数据交错(concat操做符是链接不会出现交错),若是在合并的途中出现错误,就会当即将错误提交给订阅者,将终止合并后的Observable。
mergeDelayError:mergeDelayError
操做符相似于merge
操做符,惟一不一样就是若是在合并途中出现错误,不会当即发射错误通知,而是保留错误直到合并后的Observable将全部的数据发射完成,此时才会将onError提交给订阅者。
例如:一个界面有两个网络接口请求
//这个请求故意延时5秒再发送->最后测试结果发现,并非searchObservable等待mobileObservable5秒后再发送,目的验证无序的概念 Observable<ResultBean> mobileObservable = Observable.timer(5, TimeUnit.SECONDS).flatMap(new Function<Long, ObservableSource<ResultBean>>() { @Override public ObservableSource<ResultBean> apply(@NonNull Long aLong) throws Exception { return EasyHttp.get("http://apis.juhe.cn/mobile/get") .params("phone", "18688994275") .params("dtype", "json") .params("key", "5682c1f44a7f486e40f9720d6c97ffe4") .execute(new CallClazzProxy<TestApiResult1<ResultBean>, ResultBean>(ResultBean.class) { }); } }); Observable<Content> searchObservable = EasyHttp.get("/ajax.php") .baseUrl("http://fy.iciba.com") .params("a", "fy") .params("f", "auto") .params("t", "auto") .params("w", "hello world") //采用代理 .execute(new CallClazzProxy<TestApiResult6<Content>, Content>(Content.class) { }); //Observable.merge(mobileObservable,searchObservable).subscribe(new BaseSubscriber<Object>() { Observable.mergeDelayError(mobileObservable,searchObservable).subscribe(new BaseSubscriber<Object>() { @Override public void onError(ApiException e) { showToast(e.getMessage()); } @Override public void onNext(@NonNull Object object) { //为何用Object接收,由于两个接口请求返回的数据类型不是同样的,若是是同样的就用具体的对象接收就能够了, // 再也不须要instanceof麻烦的判断 if (object instanceof ResultBean) {//mobileObservable 返回的结果 //处理 ResultBean逻辑 } else if (object instanceof Content) { //处理 Content逻辑 } showToast(object.toString()); } });
其中提到一个概念:合并的Observable发射的数据交错,也就是发射的数据无序,怎么理解它呢?例如:代码中merge(mobileObservable,searchObservable)
合并的mobileObservable和searchObservable,其中mobileObservable在前,并不表明订阅的subscribe->onNext(@NonNull Object object)
就先返回来数据,也多是合并的searchObservable数据先返回回来。
延伸讲解,刚才讲解了merge
操做符是无序的,若是想保证有序执行怎么办呢,采用Rxjava的concat
操做符
看完场景七和场景八:merge和zip的区别究竟是什么呢?
merge和zip都是将多个Observalbe发射的数据项,合并到一个Observable中再发射出去。只是在发射的结果上有所不一样。例若有3个网络请求的Observalbe,zip是等待这3个请求都完成后才一块儿返回,既onNext调用1次。merge是3个Observalbe分别返回,并且无序,既onNext调用3次,至关于把3个原本分散的网络请求。写在同一个地方合并起来执行。
merge、mergeDelayError都是合并,可是须要注意两者区别。
- merge合并的请求,若是有一个接口报错了,就立马报错,会终止整个流,另外的接口也不会请求。
- mergeDelayError合并的请求,若是有一个接口报错了,会延迟错误处理,后面的接口会继续执行没有被中断。
这里主要是讲解RxEasyHttp如何结合rxbinding库compile 'com.jakewharton.rxbinding2:rxbinding:2.0.0'
来使用。对rxbinding库不了解的,能够本身去学习一下,这里不详细介绍。在页面请求中可能操做太快致使同一个网络请求重复执行,这里结合view来讲明,点击一个按钮去请求网络,点击太快就会重复执行-界面防抖。
避免重复请求:利用Rxjavad的throttleFirst
操做符。
throttleFirst:会按期发射这个时间段里源Observable发射的第一个数据。
例如:点击按钮去请求网络,1s内避免点击过快重复请求
RxView.clicks(view).throttleFirst(1, TimeUnit.SECONDS).flatMap(new Function<Object, ObservableSource<ResultBean>>() { @Override public ObservableSource<ResultBean> apply(@NonNull Object o) throws Exception { return EasyHttp.get("http://apis.juhe.cn/mobile/get") .params("phone", "18688994275") .params("dtype", "json") .params("key", "5682c1f44a7f486e40f9720d6c97ffe4") .execute(new CallClazzProxy<TestApiResult1<ResultBean>, ResultBean>(ResultBean.class) { }); } }).subscribe(new BaseSubscriber<ResultBean>() { @Override public void onError(ApiException e) { showToast(e.getMessage()); } @Override public void onNext(@NonNull ResultBean resultBean) { showToast(resultBean.toString()); } });
这里也是主要讲解RxEasyHttp如何结合rxbinding库compile 'com.jakewharton.rxbinding2:rxbinding:2.0.0'
来使用。对rxbinding库不了解的,能够本身去学习一下,这里不介绍用法。像即时搜索功能,在输入框中输入内容,实时搜索结果展现。
减小频繁的网络请求:利用Rxjavad的debounce
操做符。
debounce:对源Observable每产生一个结果后,若是在规定的间隔时间内没有别的结果产生,则把这个结果提交给订阅者处理,不然忽略该结果。简单的理解就是:当N个结点发生的时间太靠近(即发生的时间差小于设定的值T),debounce就会自动过滤掉前N-1个结点。
例如:即时搜索,避免每输入(删除)一个字就作一次请求,500毫秒才让它去请求一次网络,这样能够避免数据混乱,也优了app性能。
Disposable mDisposable = RxTextView.textChangeEvents(mEditText) .debounce(500, TimeUnit.MILLISECONDS).filter(new Predicate<TextViewTextChangeEvent>() { @Override public boolean test(@NonNull TextViewTextChangeEvent textViewTextChangeEvent) throws Exception { // 过滤,把输入字符串长度为0时过滤掉 String key = textViewTextChangeEvent.text().toString(); //这里能够对key进行过滤的判断逻辑 return key.trim().length() > 0; } }).flatMap(new Function<TextViewTextChangeEvent, ObservableSource<Content2>>() { @Override public ObservableSource<Content2> apply(@NonNull TextViewTextChangeEvent textViewTextChangeEvent) throws Exception { String key = textViewTextChangeEvent.text().toString(); Log.d("test", String.format("Searching for: %s", textViewTextChangeEvent.text().toString())); return EasyHttp.get("/ajax.php") .baseUrl("http://fy.iciba.com") .params("a", "fy") .params("f", "auto") .params("t", "auto") .params("w", key) //采用代理 .execute(new CallClazzProxy<TestApiResult6<Content2>, Content2>(Content2.class) { }); } }).subscribeWith(new BaseSubscriber<Content2>() { @Override protected void onStart() { } @Override public void onError(ApiException e) { mTextView.setText(e.getMessage()); } @Override public void onNext(@NonNull Content2 content) { mTextView.setText(content.toString()); } }); //取消请求 //EasyHttp.cancelSubscription(mDisposable);
网络数据缓存在RxEasyHttp网络库中已经封装了,也就是开发者在使用网络库过程当中没必要关心缓存具体的实现,经过RxEasyHttp库文档讲解调用一些配置参数就能够实现须要的缓存功能了。这里主要讲解的是不使用okhttp和Retrofit的缓存,而是介绍本身如何封装缓存。RxEasyHttp网络库除了支持无缓存和默认的http缓存以外,又提供了其它6种场景缓存:
FIRSTREMOTE:先请求网络,请求网络失败后再加载缓存
FIRSTCACHE:先加载缓存,缓存没有再去请求网络
ONLYREMOTE:仅加载网络,但数据依然会被缓存
ONLYCACHE:只读取缓存,缓存没有会返回null
CACHEANDREMOTE:先使用缓存,无论是否存在,仍然请求网络,CallBack会回调两次.
CACHEANDREMOTEDISTINCT:先使用缓存,无论是否存在,仍然请求网络,CallBack回调不必定是两次,若是发现请求的网络数据和缓存数据是同样的,就不会再返回网络的回调,既回调一次。不然不相同仍然会回调两次。(目的是为了防止数据没有发生变化,也须要回调两次致使界面无用的重复刷新)
若是对这部分源码敢兴趣的请查看RxEasyHttp源码,因为此部分涉及的知识点和内容比较多,篇幅问题,准备在下一篇文章中单独介绍网络数据缓存的各大场景实现,敬请期待!
到这里几大经常使用的RxEasyHttp网络库结合Rxjava2场景的例子已经介绍完了,也证实了RxEasyHttp网络库与Rxjava2是能够完美结合的,在实际开发运用中的场景确定有不少种,例子是怎么也举不完的,须要灵活运用,如何写这一个本身的场景呢,我以为须要以下几点:
flatMap
,Function
等操做;文章不免有疏漏之处,若是您有任何疑议,请反馈给我,谢谢!同时你们有与网络相关更好更经常使用的场景请推荐给我,我会继续完善。喜欢请点赞,谢谢!
对场景应用感兴趣的小伙伴们能够将Demo下载下来进行参考。
项目地址
https://github.com/zhou-you/RxEasyHttp
引用文字