前言
那麼本文就將對Rxjava做一次詳細的探索,相信跟隨着博主的思路帶着自己的思考,你一定也能掌握使用這個熱門技術的要領。不僅如此,我們更要深入瞭解其內部原理,做到知其然,並且知其所以然。
關於Rxjava的基本瞭解以及其使用,我在該系列的另一篇文章中已經介紹過了。詳情關注
在另一篇文章中,從源碼出發,瞭解了其內部流程,理解Rxjava是如何實現線程的切換以及對任務邏輯的一些加工,並保持其鏈式結構
RxJava 2.x 教程及源碼揭祕(三)Rxjava操作符源碼解析
本文將從設計模式的角度,帶你完整地回顧一下RxJava整個流程中一些重要的點,讓你徹底瞭解這個流行的工具庫的內部原理
RxJava涉及的設計模式
-
觀察者模式
採用註冊(Register)或者稱爲訂閱(Subscribe)的方式,告訴被觀察者:我需要你的某某狀態,你要在它變化的時候通知我。舉個安卓中最典型的例子吧,我們空間的點擊事件監聽就是一種觀察者模式,對設置 OnClickListener 來說, View 是被觀察者, OnClickListener 是觀察者,二者通過 setOnClickListener() 方法達成訂閱關係。訂閱之後用戶點擊按鈕的瞬間,Android Framework 就會將點擊事件發送給已經註冊的 OnClickListener 。
採取這樣被動的觀察方式,既省去了反覆檢索狀態的資源消耗,也能夠得到最高的反饋速度。
我們來對比下OnclickListener和RxJava
Buton持有OnClickListener的引用,當Button觸發了點擊事件,調用OnClickListene的OnClik方法,這就是觀察者的流程,相信集合上面圖片的對比,你已經知道了RxJava中各部分分別對應的角色。
RxJava 有四個基本概念:
Observable
(可觀察者,即被觀察者)、Observer
(觀察者)、subscribe
(訂閱)、事件。Observable
和Observer
通過subscribe()
方法實現訂閱關係,從而Observable
可以在需要的時候發出事件來通知Observer
。 -
裝飾者模式
RxJava所有操作符的共同原理:lift()
這些變換雖然功能各有不同,但實質上都是針對事件序列的處理和再發送。而在 RxJava 的內部,它們是基於同一個基礎的變換方法:
lift(Operator)
。首先看一下lift()
的內部實現(僅核心代碼):// 注意:這不是 lift() 的源碼,而是將源碼中與性能、兼容性、擴展性有關的代碼剔除後的核心代碼。 // 如果需要看源碼,可以去 RxJava 的 GitHub 倉庫下載。 public <R> Observable<R> lift(Operator<? extends R, ? super T> operator) { return Observable.create(new OnSubscribe<R>() { @Override public void call(Subscriber subscriber) { Subscriber newSubscriber = operator.call(subscriber); newSubscriber.onStart(); onSubscribe.call(newSubscriber); } }); }
這段代碼很有意思:它生成了一個新的
Observable
並返回,而且創建新Observable
所用的參數OnSubscribe
的回調方法call()
中的實現竟然看起來和前面講過的Observable.subscribe()
一樣!然而它們並不一樣喲~不一樣的地方關鍵就在於第二行onSubscribe.call(subscriber)
中的onSubscribe
所指代的對象不同(高能預警:接下來的幾句話可能會導致身體的嚴重不適)——subscribe()
中這句話的onSubscribe
指的是Observable
中的onSubscribe
對象,這個沒有問題,但是lift()
之後的情況就複雜了點。當含有lift()
時: 1.lift()
創建了一個Observable
後,加上之前的原始Observable
,已經有兩個Observable
了; 2.而同樣地,新Observable
裏的新OnSubscribe
加上之前的原始Observable
中的原始OnSubscribe
,也就有了兩個OnSubscribe
; 3.當用戶調用經過lift()
後的Observable
的subscribe()
的時候,使用的是lift()
所返回的新的Observable
,於是它所觸發的onSubscribe.call(subscriber)
,也是用的新Observable
中的新OnSubscribe
,即在lift()
中生成的那個OnSubscribe
; 4.而這個新OnSubscribe
的call()
方法中的onSubscribe
,就是指的原始Observable
中的原始OnSubscribe
,在這個call()
方法裏,新OnSubscribe
利用operator.call(subscriber)
生成了一個新的Subscriber
(Operator
就是在這裏,通過自己的call()
方法將新Subscriber
和原始Subscriber
進行關聯,並插入自己的『變換』代碼以實現變換),然後利用這個新Subscriber
向原始Observable
進行訂閱。 這樣就實現了lift()
過程,有點像一種代理機制,通過事件攔截和處理實現事件序列的變換。 -
精簡掉細節的話,也可以這麼說:在
Observable
執行了lift(Operator)
方法之後,會返回一個新的Observable
,這個新的Observable
會像一個代理一樣,負責接收原始的Observable
發出的事件,並在處理後發送給Subscriber
。如果你更喜歡具象思維,可以看圖:
或者可以看動圖:
兩次和多次的
lift()
同理,如下圖:
爲什麼subscribeOn()
進行了接收線程的切換,發射線程僅僅響應了第一個 newThread
,但每調用一次 observeOn()
,線程便會切換一次。subscribeOn()
的位置放在哪裏都可以,但它是隻能調用一次的。
我們來了解一下其訂閱與數據傳遞的流程
RxJava的訂閱與數據傳遞流程
訂閱過程:從下往上
1.終點Observer訂閱了map返回的ObserableMap。
2.map的Observable(ObservableMap)被訂閱時,會訂閱其上游的Observable,用於訂閱上游的Observer是一個裝飾者(MapObserver),內部保存了下游Observer,上游發數據時,傳遞給下游。
3.以此類推,源頭Observable被訂閱時,他會向Observer發數據
數據傳遞過程:從上往下
1.源頭Observable傳遞數據給下游Observer
2.Observer收到數據對其變換的操作之後(就是Function執行之後),在調用內部保存的下游Observer的onNext()發送數據給下游
3.以此類推,最終把數據送達至終點Observer
通過對這兩個流程的理解,你會發現,訂閱是從下往上,所以第一個subscribeOn()
最後被調用,所以無論你調用多少次,只響應第一個。同理,數據的發送是自上而下的,最下面,就是最後一個observeOn()
被調用被最後調用,所以無論你調用多少次,都會響應最後一次;