首先是一个最基础的概念,什么是Observable和Subscriber哪个是观察者,哪个是被观察者,这是理解整个框架的基础。从字面上理解,Observable是可观测的,Subscriber是订阅者的意思,另外看Subscriber的实现
![](https://img.haomeiwen.com/i1002598/ddccf5f794b17779.png)
Subscriber实现了观察者Observer。
所以切记Observable是我们说的观察者模式中的被观察者,主要用来提供数据支持,而Subscriber才是观察者,观察数据的变化,对数据进行相应的处理,返回最终的结果。
另外俩个容易混淆的概念是:
在RxAndroid中观察者模式的订阅关系是 被观察者订阅观察者。
subscribeOn()
是设置被观察者执行所在的线程,observeOn()
设置观察者执行所在的线程
下面通过几个问题,来理解RxAndroid源码
1、Observable
和Subscriber
是如何进行关联的?
在源码中Observable
类中有subscribe(Subscriber<? super T> subscriber)
方法,这个方法的内部实现如下:
![](https://img.haomeiwen.com/i1002598/a245347a8f445635.png)
目的是将观察者
subscriber
和当前的被观察者Observable.this
进行绑定,这段代码就解释了,我们创建的观察者是怎么和被观察者扯上关系的。
2、被观察者和观察者在订阅的过程中都做了哪些事情?
这里使用了被观察者Observable
类的非常重要的一个成员变量onSubscriber
。
![](https://img.haomeiwen.com/i1002598/cf4b4901fb02b77a.png)
这个成员变量是用来做什么的那?看看他的实现
![](https://img.haomeiwen.com/i1002598/ed5979b952ded55c.png)
继承自Action1,另外Action1的泛型是观察者
Subscriber
。看一下OnSubscribe
类的使用
![](https://img.haomeiwen.com/i1002598/a32d75b36c0ebd27.png)
当被观察者Observable
订阅观察者Subscriber
的时候会调用如上的一段代码,观察者会做为OnSubscribe类的call(T t)
方法的参数进行传递。所以OnSubscribe<T>
接口担当了Observable
调用Subscriber
的角色,也是订阅操作核心代码的所在。
3、 脱离观察者Subscriber
被观察者Observable
能单独执行吗?
答案是不能,因为当执行Observable
的subscribe()
方法时,如果Subscriber
为空,将直接抛 IllegalArgumentException。
![](https://img.haomeiwen.com/i1002598/757f82f643fef237.png)
4、如果能保证观察者的onCompleted()
、onError()
方法不重复执行?并且onNext()
方法可以执行0次或者多次,但是当onCompleted()
、onError()
其中一个执行之后,onNext()
就不在执行?
为解决这个问题作者引入了SafeSubscriber
类,看此类的实现,继承自观察者SubScriber
,重写了Subscriber
的以上三个方法。
![](https://img.haomeiwen.com/i1002598/4751720883508fe5.png)
另外定义一个两个成员变量,actual
用来存储传递过来的原观察者,done
用来判读当前观察者的onCompleted()
、onError()
有没有执行过,如果已经执行过,则不再执行,看源码
![](https://img.haomeiwen.com/i1002598/348f0afcc7edf12a.png)
如果没有执行过,直接调用传递过来的观察者的方法。
![](https://img.haomeiwen.com/i1002598/fa541cecf8322b94.png)
SafeSubscriber
类在Observable
中的使用
![](https://img.haomeiwen.com/i1002598/884ec57db48fd7b4.png)
在被观察者的订阅方法subscribe()
里将观察者进行安全置换。
5、 线程切换如何实现的?
写了一个简单的RxJava实现线程切换的例子,代码如下
![](https://img.haomeiwen.com/i1002598/22e8609aaf1c5dc2.png)
在断点调试的过程中,可以看到,程序不会直接执行Observable.just中的代码。
![](https://img.haomeiwen.com/i1002598/b0c4a0fa673f9d6b.png)
分析一下产生的结果很有意思,生成一个静态的hook对象,分别生成一个被观察者observable对象和一个观察者Subscriber对象,最主要的是生成Observable.onSubscribe成员变量,这个对象存储了执行被观察者Observable的代码的所在的线程OperatorSubscribeOn
,使用Handler实现和观察者Subscriber所在的线程OperatorObserveOn
,使用线程池实现。
![](https://img.haomeiwen.com/i1002598/7fc5472724aff5d0.png)
6、 为什么在非主线程仍然能跟新UI,为什么不会爆异常?
正在解决
网友评论