首先是一個最基礎的概念,什么是Observable和Subscriber哪個是觀察者,哪個是被觀察者,這是理解整個框架的基礎。從字面上理解,Observable是可觀測的,Subscriber是訂閱者的意思,另外看Subscriber的實現(xiàn)
Subscriber實現(xiàn)了觀察者Observer。
所以切記Observable是我們說的觀察者模式中的被觀察者,主要用來提供數(shù)據(jù)支持,而Subscriber才是觀察者,觀察數(shù)據(jù)的變化,對數(shù)據(jù)進行相應的處理,返回最終的結果。
另外倆個容易混淆的概念是:
在RxAndroid中觀察者模式的訂閱關系是 被觀察者訂閱觀察者。
subscribeOn()
是設置被觀察者執(zhí)行所在的線程,observeOn()
設置觀察者執(zhí)行所在的線程
下面通過幾個問題,來理解RxAndroid源碼
1、Observable
和Subscriber
是如何進行關聯(lián)的?
在源碼中Observable
類中有subscribe(Subscriber<? super T> subscriber)
方法,這個方法的內(nèi)部實現(xiàn)如下:
目的是將觀察者
subscriber
和當前的被觀察者Observable.this
進行綁定,這段代碼就解釋了,我們創(chuàng)建的觀察者是怎么和被觀察者扯上關系的。
2、被觀察者和觀察者在訂閱的過程中都做了哪些事情?
這里使用了被觀察者Observable
類的非常重要的一個成員變量onSubscriber
。
這個成員變量是用來做什么的那?看看他的實現(xiàn)
繼承自Action1,另外Action1的泛型是觀察者
Subscriber
??匆幌?code>OnSubscribe類的使用
當被觀察者Observable
訂閱觀察者Subscriber
的時候會調(diào)用如上的一段代碼,觀察者會做為OnSubscribe類的call(T t)
方法的參數(shù)進行傳遞。所以OnSubscribe<T>
接口擔當了Observable
調(diào)用Subscriber
的角色,也是訂閱操作核心代碼的所在。
3、 脫離觀察者Subscriber
被觀察者Observable
能單獨執(zhí)行嗎?
答案是不能,因為當執(zhí)行Observable
的subscribe()
方法時,如果Subscriber
為空,將直接拋 IllegalArgumentException。
4、如果能保證觀察者的onCompleted()
、onError()
方法不重復執(zhí)行?并且onNext()
方法可以執(zhí)行0次或者多次,但是當onCompleted()
、onError()
其中一個執(zhí)行之后,onNext()
就不在執(zhí)行?
為解決這個問題作者引入了SafeSubscriber
類,看此類的實現(xiàn),繼承自觀察者SubScriber
,重寫了Subscriber
的以上三個方法。
另外定義一個兩個成員變量,actual
用來存儲傳遞過來的原觀察者,done
用來判讀當前觀察者的onCompleted()
、onError()
有沒有執(zhí)行過,如果已經(jīng)執(zhí)行過,則不再執(zhí)行,看源碼
如果沒有執(zhí)行過,直接調(diào)用傳遞過來的觀察者的方法。
SafeSubscriber
類在Observable
中的使用
在被觀察者的訂閱方法subscribe()
里將觀察者進行安全置換。
5、 線程切換如何實現(xiàn)的?
寫了一個簡單的RxJava實現(xiàn)線程切換的例子,代碼如下
在斷點調(diào)試的過程中,可以看到,程序不會直接執(zhí)行Observable.just中的代碼。
分析一下產(chǎn)生的結果很有意思,生成一個靜態(tài)的hook對象,分別生成一個被觀察者observable對象和一個觀察者Subscriber對象,最主要的是生成Observable.onSubscribe成員變量,這個對象存儲了執(zhí)行被觀察者Observable的代碼的所在的線程OperatorSubscribeOn
,使用Handler實現(xiàn)和觀察者Subscriber所在的線程OperatorObserveOn
,使用線程池實現(xiàn)。
6、 為什么在非主線程仍然能跟新UI,為什么不會爆異常?
正在解決