友好 RxJava2.x 原始碼解析(一)基本訂閱流程

揪克發表於2017-12-01

系列文章:

本文 csdn 地址:友好 RxJava2.x 原始碼解析(一)基本訂閱流程

本文基於 RxJava 2.1.3

前言

本文基於讀者會使用 RxJava 2.x 而講解,基本原理不涉及,示例只純粹為示例而示例。

示例程式碼

示例原始碼:
    Observable
            .create(new ObservableOnSubscribe<String>() {
                @Override
                public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                    emitter.onNext("1");
                    emitter.onNext("2");
                    emitter.onNext("3");
                    emitter.onComplete();
                }
            })
            .subscribe(new Observer<String>() {
                @Override
                public void onSubscribe(Disposable d) {
                    Log.e("TAG", "onSubscribe():  ");
                }

                @Override
                public void onNext(String s) {
                    Log.e("TAG", "onNext():  " + s);
                }

                @Override
                public void onError(Throwable e) {

                }

                @Override
                public void onComplete() {
                    Log.e("TAG", "onComplete():  ");
                }
            });
複製程式碼

輸出結果:

E/TAG: onSubscribe():  
E/TAG: onNext():  1
E/TAG: onNext():  2
E/TAG: onNext():  3
E/TAG: onComplete():  
複製程式碼

訂閱流程解析

我們知道 subscribe() 方法是 Observable 和 Observer 的連線點,所以首先戳進 subscribe(Observer observer) 中,可以發現該方法是 Observable 類的方法,傳入了一個 Observer 物件,那首先我們需要弄明白這裡的 Observable 和 Observer 分別是什麼,觀察上方示例程式碼我們可以知道 Observer 是 new 出來的,所以我們只需要知道 Observable 是什麼,當然,這裡也很清晰,Observable 就是我們呼叫 Observable.create(ObservableOnSubscribe) 所建立出來的 Observable,來一張圖 ——

Observable.create(ObservableOnSubscribe)

Observable 和 Observer 我們都弄清楚了,接下來就是檢視 subscribe(Observer) 具體的實現了,如下 ——

@Override
public final void subscribe(Observer<? super T> observer) {
	// 略去其他原始碼
    subscribeActual(observer);
	// 略去其他原始碼
}
複製程式碼

略去非關鍵原始碼後我們發現它只做了一件事,就是呼叫 Observable#subscribeActual(observer),而在 Observable 中該方法是一個抽象方法:

protected abstract void subscribeActual(Observer<? super T> observer);
複製程式碼

這意味著我們需要去找它的子類,我們要看看它的 subscribeActual(Observer) 方法,那我們就得從 create(ObservableOnSubscribe) 著手,看它是如何將一個 ObservableOnSubscribe 物件轉換成一個 Observable 物件的——

public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
	// 略去其他原始碼
    return new ObservableCreate<T>(source);
}
複製程式碼

同樣的,刪除非關鍵原始碼之後,我們就剩下這麼一行程式碼,這也就是意味著我們需要從 ObservableCreate 這個類中去尋找 subscribeActual(Observer) 的實現了,這裡筆者需要提及兩點——

  1. 從上述方法可以看出 ObservableCreate 是 Observable 的一個子類

  2. 我們自定義的 ObservableOnSubscribe 作為一個名為 source 欄位被傳入了。事實上在 Observable 的子類實現中,它們都有一個名為 source 的欄位,指代上游 Observable(實際上是 ObservableOnSubscribe,但是我們不妨理解成就是 Observable)。

ObservableCreate#subscribeActual() 實現如下:

@Override
protected void subscribeActual(Observer<? super T> observer) {
    CreateEmitter<T> parent = new CreateEmitter<T>(observer);
    // 觸發 Observer#onSubscribe(Disposable)
    observer.onSubscribe(parent);

    try {
        // 發射事件
        source.subscribe(parent);
    } catch (Throwable ex) {
        Exceptions.throwIfFatal(ex);
        parent.onError(ex);
    }
}
複製程式碼

第5行呼叫了 Observer#onSubscribe(Disposable) ,所以我們可以知道 Observer#onSubscribe(Disposable) 是先被呼叫的,而此時 Observable 甚至還沒有開始發射事件!接下來就是呼叫了 source.subscribe(ObservableEmitter),這個方法是交由開發者去實現的,在示例程式碼是如下所寫 ——

@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
      emitter.onNext("1");
      emitter.onNext("2");
      emitter.onNext("3");
      emitter.onComplete();
  }
複製程式碼

在程式碼中我們呼叫了 CreateEmitter 物件的 onNext() 方法,所以我們需要戳入 CreateEmitter 類中看一下 onNext(T) 的具體實現(當然 onComplete() 方法等同,此處就不做擴充套件了),原始碼如下:

    @Override
    public void onNext(T t) {
		// 略去其他原始碼
        if (!isDisposed()) {
            observer.onNext(t);
        }
    }
複製程式碼

一目瞭然,噹噹前物件並不處於 DISPOSED 狀態時,那麼就將會呼叫下游 Observer 的 onNext(T) 方法,而下游 Observer 的 onNext(T) 方法也就是我們上面示例程式碼中所寫的——

public void onNext(String s) {
    Log.e("TAG", "onNext():  ");
}
複製程式碼

至此,基本訂閱流程我們就理清楚了。我們從 Observable#subscribe(Observer) 開始,將 Observer 傳給 Observable,而 Observable 又會在 onNext(T) 方法中啟用 Observer 的 onNext(T) 方法。我們在示例只涉及了少量的 Observable/Observer,事實上,我們在 RxJava 中運用的操作符都會在內部建立一個 Observable 和 Observer,雖然在 Observable#subscribeActual(Observer) 中都有自己特定的實現,但是它們大部分都是做兩個操作,一是將「下游」傳來的 Observer 根據需求進行封裝;二就是讓「上游」的 Observable subscribe() 該 Observer。

訂閱流程

經過了如上的分析後,筆者希望讀者能夠理解 RxJava2.x 的基本訂閱流程是從 Observable#subscribe(Observer) 開始的,而該方法會觸發「上游」 Observable 的 Observable#subscribeActual(Observer) 方法,而在該「上游」 Observable 中又會觸發「上游的上游」Observable 的 Observable#subscribeActual(Observer) 方法。我們不妨用以下述原始碼舉例:

Observable
    .create(new ObservableOnSubscribe<String>() {
        @Override
        public void subscribe(ObservableEmitter<String> emitter) throws Exception {
            emitter.onNext("1");
        }
    })
    .flatMap(new Function<String, ObservableSource<String>>() {
        @Override
        public ObservableSource<String> apply(String s) throws Exception {
            return Observable.just(s);
        }
    })
    .subscribe(new Observer<String>() {
        @Override
        public void onSubscribe(Disposable d) {
        }

        @Override
        public void onNext(String s) {
        }

        @Override
        public void onError(Throwable e) {
        }

        @Override
        public void onComplete() {
        }
    });
複製程式碼

另附一張圖,圖中標明瞭後面講到的「第一個 Observable」、「第二個 Observable」等名詞:

例圖

接下來用圖展示整個訂閱的流程——

Observable#subscribe(Observer) 流程

Observable#subscribe(Observer) 之前:

Observable#subscribe(Observer) 以前

準備觸發 Observable#subscribe(Observer)

準備觸發 Observable#subscribe(Observer)

Observable#subscribe(Observer) 將會導致其上游 Observable 的 subscribe(Observer) 方法被呼叫:

Observable#subscribe(Observer) 之後

上游 Observable 的 subscribe(Observer) 方法內部又會呼叫上游的上游 Observable 的 subscribe(Observer)

觸發上級 Observer

Observable#subscribe(Observer) 會呼叫 Observable#subscribeActual(Observer) ,該方法是一個抽象方法,由子類覆寫,所以展現了 Observable 的多型性,而且如何啟用上游 Observable 的 subscribe(Observer)/subscribeActual(Observer) 方法的關鍵點也在此。實現方式就在於 Observable#subscribeActual(Observer) 方法雖然是一個抽象方法,但是它的子類實現中都包含有一句 source.subscribe(Observer),其中 source 就是上游 Observable(實際上是 ObservableSource,但是我們此處不妨就理解成 Observable,畢竟我們對這個物件更熟悉一些,Observable 是 ObservableSource 介面的實現),所以就可以理解在每一個 Observable 的 subscribeActual(Observer) 方法中它都會呼叫上游的 subscribe(Observer)/subscribeActual(Observer) 方法,直至到達第一個 Observable 的 subscribe(Observer)/subscribeActual(Observer) 中。

Observer#onSubscribe(Disposable) 流程

訂閱的關係鏈理清了,但是還沒有發射事件的流程還沒出來啊,我們繼續往下走——

到達頂部 Observable 的時候,已經不能再往上走了,就要準備搞事情(準備發射事件了),此處我們就以示例程式碼中的 Observable 為例,它的 subscribeActual(Observer) 中——

@Override
protected void subscribeActual(Observer<? super T> observer) {
    CreateEmitter<T> parent = new CreateEmitter<T>(observer);
    observer.onSubscribe(parent);

    try {
        source.subscribe(parent);
    } catch (Throwable ex) {
        Exceptions.throwIfFatal(ex);
        parent.onError(ex);
    }
}
複製程式碼

它首先封裝了一個 Disposable,接下來將呼叫 Observer#onSubscribe(Disposable) 將 Disposable 作為引數傳給下一層 Observer。

Disposable 初始化

到了下一層的 Observer 的 onSubscribe(Disposable) 中,該方法中針對上一層 Disposable 做一些操作(判斷、封裝等),然後再封裝一個 Disposable 作為引數傳遞給 Observer#onSubscribe(Disposable)

Disposable 傳遞

而此時的 Observer 就是我們所自定義的 Observer——

Observer#onSubscribe(Disposable)

Observer#onNext(T) 流程

Observer#onSubscribe(Disposable) 流程結束後,就執行到第7行程式碼 Observeable.subscribe(Observer),實質上也就是——

new ObservableOnSubscribe<String>() {
    @Override
    public void subscribe(ObservableEmitter<String> emitter) throws Exception {
        emitter.onNext("1");
    }
})
複製程式碼

ps:為了方便起見,此處只分析 onNext() 執行流程。

ObservableEmitter#onNext(T) 的內部實際上會觸發 Observer 的 onNext(T) 方法——

發射事件

再向下觸發就是我們所自定義的最底層的 Observer 了——

發射事件

以示例程式碼來說,頂遊 Observable 會觸發 ObservableEmitter#onNext(T) 方法,在該方法的內部又觸發了「下游」 Observer 的 onNext(T) 方法,而在該方法內部又會觸發「下游的下游」 Observer 的 onNext(T) 方法,直至最底層的 Observer —— 我們所自定義的 Observer ——

Observer#onNext(T)

到此,一套訂閱流程就執行完畢了。

相關文章