RxJava 2.x 教程及源碼揭祕(四)由設計模式,揭祕Rxjava流程原理

前言

     那麼本文就將對Rxjava做一次詳細的探索,相信跟隨着博主的思路帶着自己的思考,你一定也能掌握使用這個熱門技術的要領。不僅如此,我們更要深入瞭解其內部原理,做到知其然,並且知其所以然。

    關於Rxjava的基本瞭解以及其使用,我在該系列的另一篇文章中已經介紹過了。詳情關注

    RxJava 2.x 教程及源碼揭祕(一)入門理解及應用

   在另一篇文章中,從源碼出發,瞭解了其內部流程,理解Rxjava是如何實現線程的切換以及對任務邏輯的一些加工,並保持其鏈式結構

RxJava 2.x 教程及源碼揭祕(三)Rxjava操作符源碼解析

本文將從設計模式的角度,帶你完整地回顧一下RxJava整個流程中一些重要的點,讓你徹底瞭解這個流行的工具庫的內部原理

 

RxJava涉及的設計模式

  1. 觀察者模式           

    採用註冊(Register)或者稱爲訂閱(Subscribe)的方式,告訴被觀察者:我需要你的某某狀態,你要在它變化的時候通知我。舉個安卓中最典型的例子吧,我們空間的點擊事件監聽就是一種觀察者模式,對設置 OnClickListener 來說, View 是被觀察者, OnClickListener 是觀察者,二者通過 setOnClickListener() 方法達成訂閱關係。訂閱之後用戶點擊按鈕的瞬間,Android Framework 就會將點擊事件發送給已經註冊的 OnClickListener 。

    採取這樣被動的觀察方式,既省去了反覆檢索狀態的資源消耗,也能夠得到最高的反饋速度。

    我們來對比下OnclickListener和RxJava

    OnClickListener 觀察者模式

    通用觀察者模式

    Buton持有OnClickListener的引用,當Button觸發了點擊事件,調用OnClickListene的OnClik方法,這就是觀察者的流程,相信集合上面圖片的對比,你已經知道了RxJava中各部分分別對應的角色。

    RxJava 有四個基本概念:Observable (可觀察者,即被觀察者)、 Observer (觀察者)、 subscribe (訂閱)、事件。ObservableObserver 通過 subscribe() 方法實現訂閱關係,從而 Observable 可以在需要的時候發出事件來通知 Observer

  2. 裝飾者模式   

    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() 後的 Observablesubscribe() 的時候,使用的是 lift() 所返回的新的 Observable ,於是它所觸發的 onSubscribe.call(subscriber),也是用的新 Observable 中的新 OnSubscribe,即在 lift() 中生成的那個 OnSubscribe;                                                                                                                                                                        4.而這個新 OnSubscribecall() 方法中的 onSubscribe ,就是指的原始 Observable 中的原始 OnSubscribe ,在這個 call() 方法裏,新 OnSubscribe 利用 operator.call(subscriber) 生成了一個新的 SubscriberOperator 就是在這裏,通過自己的 call() 方法將新 Subscriber 和原始 Subscriber 進行關聯,並插入自己的『變換』代碼以實現變換),然後利用這個新 Subscriber 向原始 Observable 進行訂閱。                                                                                                                                   這樣就實現了 lift() 過程,有點像一種代理機制,通過事件攔截和處理實現事件序列的變換。

  3. 兩次 lift

    精簡掉細節的話,也可以這麼說:在 Observable 執行了 lift(Operator) 方法之後,會返回一個新的 Observable,這個新的 Observable 會像一個代理一樣,負責接收原始的 Observable 發出的事件,並在處理後發送給 Subscriber

    如果你更喜歡具象思維,可以看圖:

    lift() 原理圖

    或者可以看動圖:

    lift 原理動圖

    兩次和多次的 lift() 同理,如下圖:兩次 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()被調用被最後調用,所以無論你調用多少次,都會響應最後一次;

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章