0°

RxJava 2.0 全面解析

内容预览:
  • “ 铺垫 假如你还不是很熟悉RxJava,或者对于背压这个概念(2.0更新中会...~
  • “ 添加依赖 这个估计得放在最前面~
  • 其实这种设计可以说还是符合逻辑的,因为取消订阅这个动作就只有观察者...~

始发于微信公众号: 程序员小乐

分享编程技能、互联网技术、生活感悟、打造干货分享平台,将总结的技术、心得、经验分享给大家,这里不只限于技术!学无止境,不求尽如人意,但求问心无愧。让学习成为一种美、一种习惯。值得爱学习的你去关注,感觉有帮助转发分享让更多的人去关注!点击上方 蓝字 关注!



作者:拉丁吴

链接:http://www.jianshu.com/p/220955eefc1f
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

RxJava 2.0 全面解析—– 由   分享


每日英语

don’t corrupted themselves, life is not only an opportunity, try to。 

不要堕落了自己,人生并不只有一次机会,努力把握。

前言



之前写RxJava相关文章的时候,就有人想让我谈谈RxJava2.0的新特性,说实话,一开始我是拒绝的。因为在我看来,RxJava2.0虽然是版本的重大升级,但总归还是RxJava,升级一个版本还能上天是咋的?了解一下它的更新文档不就好了么?真的有必要单出一篇文章来谈这个么?

但是详细的了解了RxJava2.0以及部分源码之后,我觉得还是有必要对RxJava2.0做一个说明,帮助大家对于RxJava有更好的认识。


铺垫



假如你还不是很熟悉RxJava,或者对于背压这个概念(2.0更新中会涉及到背压的概念)很模糊,希望你也能读一读下面两篇铺垫的文章:

  • 关于RxJava最友好的文章

  • 关于RxJava最友好的文章—-背压

关于背压的那篇文章本来是本文的一部分,因为篇幅过大,被剥离出去了,所以建议大家有时间也一并阅读。


正文



RxJava2.0有很多的更新,一些改动甚至冲击了我之前的文章里的内容,这也是我想写这篇文章的原因之一。不过想要写这篇文章其实也是有难度的,因为相关的资料去其实是很少的,还得自己硬着头皮上….不过俗话说得好,有困难要上,没有困难创造困难也要上。

在这里,我会按照我们之前关于RxJava的文章的讲述顺序:观察者模式,操作符,线程调度,这三个方面依次看有哪些更新。


添加依赖



这个估计得放在最前面。

Android端使用RxJava需要依赖新的包名:


//RxJava的依赖包(我使用的最新版本)    

compile ‘io.reactivex.rxjava2:rxjava:2.0.1’   

//RxAndroid的依赖包    

compile ‘io.reactivex.rxjava2:rxandroid:2.0.1’



观察者模式



首先声明,RxJava以观察者模式为骨架,在2.0中依然如此

不过此次更新中,出现了两种观察者模式:

  • Observable(被观察者)/Observer(观察者)

  • Flowable(被观察者)/Subscriber(观察者)


RxJava 2.0 全面解析


RxJava2.X中,Observeable用于订阅Observer,是不支持背压的,而Flowable用于订阅Subscriber,是支持背压(Backpressure)的。

关于背压这个概念以及它在1.0版本中的缺憾在上一篇文章中我已经介绍到了,如果你不是很清楚,我在这里在做一个介绍:背压是指在异步场景中,被观察者发送事件速度远快于观察者的处理速度的情况下,一种告诉上游的被观察者降低发送速度的策略,在1.0中,关于背压最大的遗憾,就是集中在Observable这个类中,导致有的Observable支持背压,有的不支持。为了解决这种缺憾,新版本把支持背压和不支持背压的Observable区分开来。


Observable/Observer



Observable正常用法:


RxJava 2.0 全面解析

RxJava 2.0 全面解析


这种观察者模型是不支持背压的。

啥叫不支持背压呢?

当被观察者快速发送大量数据时,下游不会做其他处理,即使数据大量堆积,调用链也不会报MissingBackpressureException,消耗内存过大只会OOM

我在测试的时候,快速发送了100000个整形数据,下游延迟接收,结果被观察者的数据全部发送出去了,内存确实明显增加了,遗憾的是没有OOM。

所以,当我们使用Observable/Observer的时候,我们需要考虑的是,数据量是不是很大(官方给出以1000个事件为分界线,仅供各位参考)


Flowable/Subscriber



RxJava 2.0 全面解析


输出如下:


RxJava 2.0 全面解析


Flowable是支持背压的,也就是说,一般而言,上游的被观察者会响应下游观察者的数据请求,下游调用request(n)来告诉上游发送多少个数据。这样避免了大量数据堆积在调用链上,使内存一直处于较低水平。

当然,Flowable也可以通过creat()来创建:

RxJava 2.0 全面解析


Flowable虽然可以通过create()来创建,但是你必须指定背压的策略,以保证你创建的Flowable是支持背压的(这个在1.0的时候就很难保证,可以说RxJava2.0收紧了create()的权限)。

根据上面的代码的结果输出中可以看到,当我们调用subscription.request(n)方法的时候,不等onSubscribe()中后面的代码执行,就会立刻执行到onNext方法,因此,如果你在onNext方法中使用到需要初始化的类时,应当尽量在subscription.request(n)这个方法调用之前做好初始化的工作;

当然,这也不是绝对的,我在测试的时候发现,通过create()自定义Flowable的时候,即使调用了subscription.request(n)方法,也会等onSubscribe()方法中后面的代码都执行完之后,才开始调用onNext。


TIPS: 尽可能确保在request()之前已经完成了所有的初始化工作,否则就有空指针的风险。


其他观察者模式



当然,除了上面这两种观察者,还有一类观察者

  • Single/SingleObserver

  • Completable/CompletableObserver

  • Maybe/MaybeObserver

其实这三者都差不多,Maybe/MaybeObserver可以说是前两者的复合体,因此以Maybe/MaybeObserver为例简单介绍一下这种观察者模式的用法


RxJava 2.0 全面解析


上面就是Maybe/MaybeObserver的普通用法,你可以看到,实际上,这种观察者模式并不用于发送大量数据,而是发送单个数据,也就是说,当你只想要某个事件的结果(true or false)的时候,你可以用这种观察者模式


这是上面那些被观察者的上层接口:


RxJava 2.0 全面解析


其实我们可以看到,每一种观察者都继承自各自的接口,这也就把他们能完全的区分开,各自独立(特别是Observable和Flowable),保证了他们各自的拓展或者配套的操作符不会相互影响。

例如flatMap操作符实现:

RxJava 2.0 全面解析


假如你想为Flowable写一个自定义的操作符,那么只要保证Function< Publisher >中的类型实现了Publisher接口即可。这么说可能很抽象,大家不理解其实也没关系,因为并不推荐大家自定义操作符,RxJava中的操纵符的组合已经可以满足大家的需求了。

当然,你也会注意到上面那些接口中的subscribe()方法的返回类型为void了,在1.X中,这个方法一般会返回一个Subscription对象,用于取消订阅。现在,这个功能的对象已经被放到观察者Observer或者subscriber的内部实现方法中了,

Flowable/Subscriber


RxJava 2.0 全面解析


上面的实例中,onSubscribe(Subscription s)传入的参数s就肩负着取消订阅的功能,当然,他也可以用于请求上游的数据。

在Observable/observer中,传入的参数是另一个对象

Observable/Observer

RxJava 2.0 全面解析


在Observer接口中,onSubscribe(Disposable d)方法传入的Disposable也是用于取消订阅,基本功能是差不多的,只不过命名不一致,大家知道就好。

其实这种设计可以说还是符合逻辑的,因为取消订阅这个动作就只有观察者(Observer等)才能做的,现在把它并入到观察者内部,也算顺理成章吧。

最后再提一点更新,就是被观察者不再接收null作为数据源了。


操作符相关



这一块其实可以说没什么改动,大部分之前你用过的操作符都没变,即使有所变动,也只是包名或类名的改动。大家可能经常用到的就是Action和Function。


Action相关



之前我在文章里介绍过关于Action这类接口,在1.0中,这类接口是从Action0,Action1…往后排(数字代表可接受的参数),现在做出了改动

Rx1.0———–Rx2.0

Action1——–Action
Action1——–Consumer
Action2——–BiConsumer
后面的Action都去掉了,只保留了ActionN


Function相关



同上,也是命名方式的改变

上面那两个类,和RxJava1.0相比,他们都增加了throws Exception,也就是说,在这些方法做某些操作就不需要try-catch

例如:

RxJava 2.0 全面解析


Files.readLines(name)这类io方法本来是需要try-catch的,现在直接抛出异常,就可以放心的使用lambda ,保证代码的简洁优美。


doOnCancel/doOnDispose/unsubscribeOn



以doOnCancel为例,大概就是当取消订阅时,会调用这个方法,例如:


RxJava 2.0 全面解析


take新操符会取消后面那些还未被发送的事件,因而会触发doOnCancel

其他的一些操作符基本没变,或者只是改变了名字,在这里就不一一介绍了,需要提一下的是,很多操作符都有两套,一套用于Observable,一套用于Flowable。

线程调度



可以说这一块儿基本也没有改动,如果一定要说的话。

  • 那就是去掉了Schedulers.immediate()这个线程环境

  • 移除的还有Schedulers.test()(我好像从来没用过这个方法)

  • io.reactivex.Scheduler这个抽象类支持直接调度自定义线程任务(这个我也没怎么用)


补充



如果你想把自己的RxJava1.0的迁移到2.0的版本,可以使用这个库RxJava2Interop ,在github上可以找到,它可以在Rxjava1.0和2.0之间相互转换,也就是说,不仅可以把1.0的代码迁移到2.0,你还可以把2.0的代码迁移到1.0,哈哈。


补充2



在RxJava1.0中,有的人会使用CompositeSubscription来收集Subscription,来统一取消订阅,现在在RxJava2.0中,由于subscribe()方法现在返回void,那怎么办呢?

其实在RxJava2.0中,Flowable提供了subscribeWith这个方法可以返回当前订阅的观察者,并且通过ResourceSubscriber DisposableSubscriber等观察者来提供 Disposable的接口

所以,如果想要达成RxJava1.0的效果,现在应该是这样做:

CompositeDisposable composite = new CompositeDisposable();

composite.add(Flowable.range(1, 8).subscribeWith(subscriber));

这个subscriber 应该是 ResourceSubscriber 或者 DisposableSubscriber 的实例。


结尾



其实从整篇文章的分析来看,改动最大的还是观察者模式的实现,被拆分和细化了,主要分成了Observable和Flowable两大类,当然还有与之相关联的其他变动,总体来看这一版本可以说是对于观察者和被观察者的重构

RxJava2.0的范例代码我没精力去写了,也正巧有位外国朋友已经写了RxJava2.0的demo,下面是他的项目地址:

在github上搜索:RxJava2-Android-Samples

当然,学习2.0 的过程中有什么问题也可以在这里留言讨论。


附录



下面我截图展示一下2.0相对于1.0的一些改动的细节,仅做参考。

RxJava 2.0 全面解析

RxJava 2.0 全面解析

RxJava 2.0 全面解析

RxJava 2.0 全面解析

RxJava 2.0 全面解析

RxJava 2.0 全面解析

RxJava 2.0 全面解析

RxJava 2.0 全面解析


其实这些都是官方给出的列表,截图在这里只是方便大家观摩。


如果您觉得不错,请别忘了分享到您的朋友圈让更多的人看到!! 您的举手之劳,就是对我最好的支持,非常感谢!



RxJava 2.0 全面解析

每日掏心话

做你没做过的事情叫成长,做你不愿意做 的 事 情 叫 改变,做你不敢做的事情叫突破 。


RxJava 2.0 全面解析


推荐阅读





小密圈
这里聚集了业界内的大牛,值得各位大牛的加入!


RxJava 2.0 全面解析

看完本文有收获?请转发分享给更多人
关注「杨守乐」,提升编程技能

【QQ技术群】279126311 []
【QQ技术群】484572225 [未]

以上就是:RxJava 2.0 全面解析 的全部内容。

本站部分内容来源于互联网和用户投稿,如有侵权请联系我们删除,谢谢。
Email:[email protected]


0 条回复 A 作者 M 管理员
    所有的伟大,都源于一个勇敢的开始!
欢迎您,新朋友,感谢参与互动!欢迎您 {{author}},您在本站有{{commentsCount}}条评论