初识Rxjava

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_42171948/article/details/88317896

Rxjava

Rxjava内容很多很深,经过这两天的学习实践,也就稍微理解了点皮毛,写篇文章记录一下学习成果哈哈。

什么是Rxjava,为什么要用Rxjava

晦涩难懂的介绍就不说了,也说不出来。我的理解就是Rxjava是一个和异步操作有关的库。

那么我们可能会很快就提问了,异步操作?那我们可以用 Android 创造的 AsyncTask 和Handler 呀?为什么要用Rxjava呢?这个家伙好在哪?

朋友们,一开始我也有这样的疑问,但经过一番了解后发现,简洁,在异步操作的逻辑较为简单的情况下,保持简洁,在逻辑复杂的情况下,依然优雅地保持简洁。而AsyncTask 和Handler 呀,在逻辑复杂的情况下,可就有点难过了。什么?你不信?好的,那就继续看下去吧。
+栗子
观察-订阅模式,事件流

一.观察-订阅

这俩是比较重要但不难理解的概念。什么是观察订阅?

还是要先联想到我们最为熟悉的监听器和广播机制。当一个控件注册了相关操作的监听,那么当这个操作发生的时候,相关监听器就会被触发,从而进行我们早已定义好的事情。广播的思想也类似,在注册了相关的广播之后,当发生的时候就会执行已定义好的事情。

那么Rxjava的观察订阅也类似,比如说Button.setOnClickListener(View.OnclickListener),观察者(Observer/Subscriber)就是Button,写好了被触发之后要做什么。被观察者(Observable)里的内容一般就是View.OnclickListener,写好了什么事件会触发。

二.事件流

我把观察者被观察者看成一个管道的两头,Observable.subscribe(Observer)将两头连接起来。Observable是下游,Observer是上游。下游向上游发送事件。上游处理事件。这里的事件可以是你感兴趣的任何东西(触摸事件,接口调用返回的数据等)。

创建事件流的上游下游及阻断流
看看下图:
enter description here

(1)创建Observable

创建下游Observable有几种方法,传统的是用Observable.create(OnSubscribe),2.0是用Emitter发送事件。一般我们的创建用的是just(T)。为什么?因为简洁。just里面的参数如果是一个,就相当于调用了create(),多个的话就相当于调用了from(T[ ])。好的,那么提一下from(T[ ])吧。

from(T[ ])的话是将数据序列按顺序将一个个的T发送给上游,所以就相当于发送了多个事件。看到这里,聪明的你一定会猜到just和from的关系了吧,是的,just是将对象当成一个传给上游,from是将其分成一个一个的对象传上去。create,just,from三者的关系其实还是很紧密的。有兴趣的小伙伴可以去研究研究一下源码。

(2)创建Observer

new Observer的话就少不了在Observer里面处理一下事件触发之后的响应操作啦。

有必要先了解一下Observer的相关回调方法,有onSubscribe(),onNext(),onComplete(),onError()。

一个一个来:

onSubscribe(Disposable):我们通过查看源码便可发现,该回调方法是最早调用的。参数Disposable又是什么呢?我们一般在该回调里面进行什么操作呢?留个悬念,且听下回分解。

onNext():这个回调方法是特别关键的。我们经常重写该方法,在方法体内定义接收到事件后想进行的操作。参数和Observer创建时的参数是一致的。

onComplete():在该发送的事件都发送完毕之后,onComplete()会被自动或主动调用。在onComplete()被调用之后,会自动dispose(),阻断掉事件流。

onError():在发送事件遇到错误时会回调该方法。onComplete()会被自动或主动调用。在onComplete()被调用之后,会自动dispose(),阻断掉事件流。

所以在主动调用的时候呢,调用了onError()就不能再调用onComplete(),主动调用就是在创建Observable的时候调用。当然不主动调用,在所有事件都发送完毕之后,onComplete()也会被自动调用的。

(3)创建连接

当数据准备好,Observable和Observer创建完毕的时候。我们就可以调用Observable.subscribe(Observer)将管道连接起来啦。连了之后呢,下游就开始向上游发送事件,这样子就打通了脉络,一路畅通啦。

(4)Disposable类

dispose():主动解除订阅
isDisposed():查询是否解除订阅 true 代表 已经解除订阅

关于操作符

Rxjava有很多好用的操作符,这里记录一下几个比较常用的。

(1)create(OnSubscribe)创建Observable

(2)just 创建Observable,将传入的参数当成一个对象传输到上游,也可以传多个参数,相当于调用了from()

(3)from 创建Observable,将传入的参数当成多个对象传输到上游

(4)map 对原始的参数进行处理,返回值还是基本的类型

(5)flatMap 传入的参数是Observable,传出的也是Observable。flatMap输出的新的Observable正是我们在Subscriber想要接收的。

(6)concatMap 将flatMap返回的无序Observable转化为有序Observable

(7)subscribeOn 改变调用前代码所在的线程,一般用来设定被订阅者所在的线程

(8)observeOn 改变调用后代码所在的线程,一般用来设定订阅者所在的线程

(9)filter 输出和输入相同的元素,并且会过滤掉那些不满足检查条件的。

(10)take 输出最多指定数量的结果

(11)subscribe 将上游和下游关联起来

map和flatMap和concatMap
create和just和from

背压

(1)概念引进
第一次接触到这个概念,复制一下一种解释:被观察者发送消息太快以至于它的操作符或者订阅者不能及时处理相关的消息,从而操作消息的阻塞现象。

那我们能不能这样理解,短时间内上游来的水太多导致下游来不及处理或者没能力处理这么大的水流。所以被堵住了。在RxJava中,阻塞不一定会出现异常,但是肯定会多少对系统的性能和功能造成一定的影响。

那我就想了,那就下游能收多少水就发多少水咯。要不就提高下游的处理能力咯。好了听说有背压这种东西,那么在2.0中是怎么实现的呢?

RXJava2.0中Observable不再支持背压,多出了Flowable来支持背压操作。在上面的图片中,我们可以看到,在官方推出了Flowable 和Subscriber用来支持背压,同样的去除了Observable对背压的支持,对的就像你上面看到的,Observable不再支持背压了,即使阻塞崩溃也不会抛出MissingBackpressureException。

(2)使用场景
由于只有在上下游运行在不同的线程中,且上游发射数据的速度大于下游接收处理数据的速度时,才会产生背压问题;
所以,如果能够确定:
1、上下游运行在同一个线程中,
2、上下游工作在不同的线程中,但是下游处理数据的速度不慢于上游发射数据的速度,
3、上下游工作在不同的线程中,但是数据流中只有一条数据
则不会产生背压问题,就没有必要使用Flowable,以免影响性能。

(3)处理方法
处理的基本策略就是减少发送事件的频率和减少发送事件的数量。这么用的:Flowable.create(FlowableOnSubscribe source, BackpressureStrategy mode).subscribe(Subscriber)

说说Flowable的用法。

Flowable.create(FlowableOnSubscribe source, BackpressureStrategy mode),创建Flowable会默认传入一个FlowableOnSubscribe和一个BackpressureStrategy。FlowableOnSubscribe很好理解就是一个就是Flowable的一个被观察者源,在回调的subscribe(FlowableEmitter)里面设定发送事件。而BackpressureStrategy就是Flowable提供的背压策略。

代码打出来就会发现,Subscriber的回调方法OnSubscribe(Subscription)是这样的,欸!参数不是Disposable了,那这个Subscription是干嘛的呢?Subscription与Disposable均是观察者与被观察者建立订阅状态后回调回来的参数,就像通过Disposable的dispose()方法可以取消Observer与Oberverable的订阅关系一样,通过Subscription的cancel()方法也可以取消Subscriber与Flowable的订阅关系。

不同的是,我们在方法里面调用request(int/Long.MAX_VALUE),通知上游,我下游能处理多少个,这样子上游才会发多少个数据给你。否则上游继续发,但下游不接受数据。这个时候上游会将事件存放在缓存池中,当然这跟缓存策略有关。缓存池的最大值默认为128.

(4)背压策略
策略的话有下面几个:
MISSING:
如果流的速度无法保持同步,可能会抛出MissingBackpressureException或IllegalStateException。采取不缓存不丢弃的策略。

BUFFER
上游不断的发出onNext请求,直到下游处理完,也就是和Observable一样了,缓存池无限大,最后直到程序崩溃

ERROR
会在下游跟不上速度时抛出MissingBackpressureException。如果缓存池里有超过128个事件就会抛出异常,提示你去处理这些事件。

DROP
会在下游跟不上速度时把onNext的值丢弃。当上游将缓存池填满之后,剩下如果还有事件,采用这种策略,则直接丢弃。所以说,有可能会丢掉自己想要的事件哦。

LATEST
与Drop策略一样,如果缓存池满了,会丢掉将要放入缓存池中的数据,不同的是,不管缓存池的状态如何,LATEST都会将最后一条数据强行放入缓存池中,来保证观察者在接收到完成通知之前,能够接收到Flowable最新发射的一条数据。

然后然后,在看大牛将这个东西结合到项目的时候,又发现了这个家伙,flowabletransformer和compose,暂时还没有去研究到底怎么回事。

先写到这吧。以后再补充修改。

猜你喜欢

转载自blog.csdn.net/qq_42171948/article/details/88317896