Android框架源碼分析——RxJava源碼分析

1、基本訂閱流程

  • 使用實例
Observable.create(ObservableOnSubscribe<String> { e -> e.onNext("A") })
    .subscribe(object : Observer<String>{
    override fun onComplete() {
    }
    override fun onSubscribe(d: Disposable) {
    }
    override fun onNext(t: String) {
    }
    override fun onError(e: Throwable) {
    }
})
  • RxJava的使用很簡單概括爲3個流程:
  1. 創建被觀察者實例發送事件
  2. 創建觀察者實例監聽處理事件
  3. 被觀察者訂閱觀察者,訂閱成功後被觀察者發送事件

2、源碼分析

2.1、Observable創建

Observable的基本使用是調用Observable.create(),create()最終創建的Observable的實現類ObserveCreate,封裝傳入的ObservableOnSubscribe,ObservableOnSubscribe負責最終的事件發送

public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
    return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source)); 
}
  • ObserveCreate:繼承Observable類,在內部保存創建時傳入的ObservableOnSubscribe實例
public final class ObservableCreate<T> extends Observable<T> {
    final ObservableOnSubscribe<T> source;
    public ObservableCreate(ObservableOnSubscribe<T> source) {
        this.source = source; //保存傳入參數
    }
}
2.2、創建觀察者實例
  • 實現Observer接口的實例
interface Observer<T>
2.3、訂閱觀察者
public final void subscribe(Observer<? super T> observer) {
        observer = RxJavaPlugins.onSubscribe(this, observer); //保存觀察者
        subscribeActual(observer); //執行觀察者的subscribeActual抽象方法,從上面知道這裏執行的是ObservableCreate()中重寫的抽象方法
    }
}

Observable.subscribe(Observer<? super T> observer)中主要作了兩件事:

  1. 封裝並保存下游設置的觀察者Observer實例,在接收事件及時響應事件
  2. 執行被觀察者的subscribeActual()觸發Observable發送事件,這裏執行的是 ObservableCreate.subscribeActual()
  • subscribeActual():此處調用的是ObservableCreate中實現的方法
@Override
protected void subscribeActual(Observer<? super T> observer) {
    CreateEmitter<T> parent = new CreateEmitter<T>(observer); 
    observer.onSubscribe(parent);  
        source.subscribe(parent); 
}

subscribeActual()中主要作以下3件事:

  1. 創建CreateEmitter包裝觀察者
  2. 執行調用觀察者的onSubscribe方法,傳入CreateEmitter實例,用於在請求時可以使用此對象控制或終止事件發送
  3. 執行傳入的source.subscribe()開始發送事件,這裏傳入的是封裝後的觀察者
  • ObservableOnSubscribe.subscribe():執行onNext()發送事件
ObservableOnSubscribe<String> { e -> e.onNext("A") } //此處的e爲CreateEmitter實例
  • CreateEmitter.onNext():調用觀察者的方法響應事件
@Override
public void onNext(T t) {
    if (!isDisposed()) { //檢查是否取消訂閱事件
        observer.onNext(t); //(1)響應接收事件
    }
}
@Override
public void onComplete() { //響應onComplete事件
    if (!isDisposed()) {
       observer.onComplete();
    }
}
@Override
public void onError(Throwable t) { //響應onError事件
}

事件發送從調用傳入CreateEmitter的next(),在next()中直接調用Observer的onNext()響應發送的事件,這裏的Observer就是前面訂閱時傳入的,此處可以看出發送的事件onNext()、onComplete()、onError()事件和觀察者監聽事件一一對應;

3、複雜訂閱流程

上面的整個流程是最基本的訂閱流程,即一層發送事件一層觀察事件,雖然簡單但卻是RxJava的原理所在,很多複雜的程序也是利用此原理一步一步封裝拓展過來的,在他們的內部是很多層簡單的邏輯,下面分析複雜的流程是如何實現的:

Observable.create(object:ObservableOnSubscribe<String>{ //第一個Observable
    override fun subscribe(e: ObservableEmitter<String>) {
        e.onNext("A")
    }
}).map(object : Function<String,String>{ //第二個Observable
    override fun apply(t: String): String {
       return "a"
    }
}).flatMap { Observable.just("A -> a”)} 第三個Observable
    .subscribe(object : Observer<String>{})

由上面的分析知道,事件訂閱是由下向上一次傳遞的過程,首先還是從訂閱subscribe開始分析,由上面知道訂閱觀察者在包裝Observer的同時,會觸發執行訂閱的Observable的subscribeActual(),此處爲第三個Observable對象,flatMap()對應Observable具體實現類爲ObservableFlatMap

AbstractObservableWithUpstream(ObservableSource<T> source) {
    this.source = source; 
}
@Override
public void subscribeActual(Observer<? super U> t) {
    source.subscribe(new MergeObserver<T, U>(t, mapper, delayErrors, maxConcurrency, bufferSize));
}

從ObservableFlatMap的構造函數中看出內部保存着source實例,使用flatMap()時會創建ObservableFlatMap實例並傳入上面創建的被觀察者實例,在subscribeActual()中首先封裝傳入的Observer,再向上調用subscribe()並傳入MergeObserver觀察者,此處的mapper就是flatMap中設置的轉換方法

  • ObservableMap

ObservableFlatMap的subscribe()方法向上調用,同樣會觸發上級Observable的subscribeActual(),向上一層執行的是map()操作符,map()的具體實現類是ObservableMap,ObservableMap中像ObservableFlatMap保存着上游的被觀察者實例和下游的觀察者實例,而且在subscribeActual()中同樣封裝Observer並調用subscribe()向上傳遞

public ObservableMap(ObservableSource<T> source, Function<? super T, ? extends U> function) {
    super(source); // 保存傳入的被觀察者source
    this.function = function;  //保存map中設置的function
} 
@Override
public void subscribeActual(Observer<? super U> t) {
    source.subscribe(new MapObserver<T, U>(t, function)); //(1)步驟和上面一樣,先封裝下游傳入的觀察者繼續向上調用,並傳遞MapObserver
}

經過map向上調用,程序再次進入ObservableCreate中,從上面分析我們知道ObservableCreate中會執行事件的發送,並觸發Observer的響應,此處第一層響應的觀察者即爲MapObserver

  • MapObserver
MapObserver(Observer<? super U> actual, Function<? super T, ? extends U> mapper) {
    super(actual);  //(1)保存下游傳來的Observer
    this.mapper = mapper; //(1)在創建map時保存傳入的轉換方法
}
@Override
public void onNext(T t) {
    U v;
    try { // (2)執行設置Function方法,獲取 經過方法處理後的數據
        v = ObjectHelper.requireNonNull(mapper.apply(t), "The mapper function returned a null value.");
    } catch (Throwable ex) {
        fail(ex);
        return;
    }
    actual.onNext(v); //(3)調用下游Observer的onNext()
}

前面的分析知道,MapObserver中保存這下游傳遞的觀察者observer和map中設置的轉換方法mapper,發送事件後執行到MapObserver的onNext()中,onNext()中首先執行mapper方法轉換髮送的事件,然後調用 actual.onNext(v)向下遊傳遞事件

  • MergeObserver:在flatMap()中創建的
MergeObserver(Observer<? super U> actual, Function<? super T, ? extends ObservableSource<? extends U>> mapper,boolean delayErrors, int maxConcurrency, int bufferSize) {
    this.actual = actual; 
    this.mapper = mapper; /
    this.observers = new AtomicReference<InnerObserver<?, ?>[]>(EMPTY);
}
@Override
public void onNext(T t) {
    ObservableSource<? extends U> p;
    try { //(2)調用設置的Function方法,此時返回的是另一個Observable對象
        p = ObjectHelper.requireNonNull(mapper.apply(t), "The mapper returned a null ObservableSource");
    } catch (Throwable e) {
        return;
    }
    subscribeInner(p); // 
}
@SuppressWarnings("unchecked")
void subscribeInner(ObservableSource<? extends U> p) {
    for (;;) {
            InnerObserver<T, U> inner = new InnerObserver<T, U>(this, uniqueId++); //創建觀察者
            if (addInner(inner)) {
                p.subscribe(inner); //(3)flapMap返回的是一個新的Observable,所以此處爲新的Observer訂閱觀察者,(單層的整個訂閱流程在flatMap()內部再走一次)
            }
            break;
    }
}
//InnerObserver
InnerObserver(MergeObserver<T, U> parent, long id) {
    this.id = id;
    this.parent = parent;  //保存MergeObserver觀察者
}
@Override
public void onNext(U t) {
    parent.drain(); //(4)新的Observable訂閱後響應觀察者,調用MergeObserver的drain()
}
void drainLoop() {
    final Observer<? super U> child = this.actual;
    child.onNext(o);
}

經上游傳遞方法執行到MergeObserver的onNext(),onNext()中首先執行轉換方法,因爲faltMap中轉換後返回新的Observable實例,所以在MergeObserver中會創建新的Observer對象即InnerObserver,然後對新的Observable對象訂閱InnerObserver對象,發送的事件會執行到InnerObserver.onNext()中,然後調用MergeObserver的drain(),在drain中獲取下游的Observer執行onNext()事件繼續向下傳遞,方法到此執行到了訂閱的Observer中,響應onNext()接收事件,最後的Observe接收事件!

4、基本操作符源碼

4.1、just()

just()方法用於傳遞單個數據,在使用just()操作符後會創建ObservableJust實例,基本功能和其他Observable一樣,在subscribeActual()中會執行run(),run()方法中調用observer.onNext(value)發送事件

protected void subscribeActual(Observer<? super T> s) {
    ScalarDisposable<T> sd = new ScalarDisposable<T>(s, value); //(1)封裝觀察者和數據
    s.onSubscribe(sd); // 
    sd.run();  //(2)執行發送內部的run()
}
@Override
public void run() {
    if (get() == START && compareAndSet(START, ON_NEXT)) {
        observer.onNext(value); //(3)接收發送事件
    }
}
4.2、ObservableFromArray

ObservableFromArray和ObservableJust功能一致,只是ObservableFromArray允許發送多個數據,在ObservableFromArray的run()方法中會循環依次發送數據

@Override
public void subscribeActual(Observer<? super T> s) {
    FromArrayDisposable<T> d = new FromArrayDisposable<T>(s, array);1)
    s.onSubscribe(d);
    d.run();
}
void run() {
    T[] a = array;
    int n = a.length;
    for (int i = 0; i < n && !isDisposed(); i++) { //(2)循環發送事件
        T value = a[i];
        actual.onNext(value);
    }
    if (!isDisposed()) {
        actual.onComplete();
    }
}
4.3、map()

由前面的源碼分析知道map()操作符創建的是ObservableMap的被觀察者,其中主要執行三個操作:

  1. 創建ObservableMap中的觀察者MapObserver的實例,保存下游傳入的Observer和map()中設置的Function實例
  2. 調用父類Observable的subscribe()發送事件
  3. 在接收事件後,在MapObserver的onNext()中先調用Function.apply()執行數據轉換,然後將結果下發到下游Observer中
4.4、 flatMap()

具體的執行邏輯和map()一致,只是在Observer中處理不同,因爲flatMap返回的是一個新的Observable,所以要對新的被觀察者進行訂閱觀察,在接受新的事件後調用下層的觀察者發送事件

4.5、 zip()

將多個Observable的事件組合一一對應發送,zip()操作符最終會創建ObservableZip實例,查看ObservableZip方法

public void subscribeActual(Observer<? super R> s) {
    ObservableSource<? extends T>[] sources = this.sources;
    int count = 0;
    count = sources.length;
    //創建ZipCoordinator實例,傳參:1、觀察者Observer;2、傳入的Function;3、Observable集合數量;4、是否推遲Error
    ZipCoordinator<T, R> zc = new ZipCoordinator<T, R>(s, zipper, count, delayError);
    zc.subscribe(sources, bufferSize); //調用subscribe()
}
  • ZipCoordinator.subscribe():爲集合中每個Observable訂閱觀察者
public void subscribe(ObservableSource<? extends T>[] sources, int bufferSize) {
    ZipObserver<T, R>[] s = observers; //創建觀察者數組,長度爲count
    int len = s.length;
    for (int i = 0; i < len; i++) {
        s[i] = new ZipObserver<T, R>(this, bufferSize); //遍歷創建ZipObserver
    }
    this.lazySet(0);
    actual.onSubscribe(this);  //響應觀察者的onSubscribe()
    for (int i = 0; i < len; i++) {
        sources[i].subscribe(s[i]); //遍歷Observable集合依次訂閱觀察者
    }
}
  • ZipObserver:從上面我們知道,數組中的Observable都會發送事件到對應的ZipObserver中,在onNext()中將發送的數據加入隊列然後調用parent.drain()方法
ZipObserver(ZipCoordinator<T, R> parent, int bufferSize) {
    this.parent = parent; 
    this.queue = new SpscLinkedArrayQueue<T>(bufferSize); //實例化一個隊列,默認大小128
}
@Override
public void onNext(T t) { //響應事件的onNext()
    queue.offer(t); 
    parent.drain(); 
}
  • 在drain()方法中使用死循環不斷查找發送的事件,直到同一組Observable的都接收到發送事件,然後調用設置的方法統一進行轉換最後返送事件
public void drain() {
    final ZipObserver<T, R>[] zs = observers;
    final Observer<? super R> a = actual; // 下游傳遞的Observer
    for (; ; ) { //兩層死循環
        for (;; ) { 
            int i = 0;
            int emptyCount = 0;
            for (ZipObserver<T, R> z : zs) {
                if (os[i] = null) { 
                    T v = z.queue.poll();  //從Observer的隊列中獲取事件
                    boolean empty = v == null;
                    if (!empty) { //如果獲取的事件不爲空,則複製os[i],否則emptyCount++
                        os[i] = v;
                    } else {
                        emptyCount++;
                    }
                } else {  ………. }
                i++; //下標++
            }
            if (emptyCount != 0) { //如果取出數據不爲空,則跳出循環,確保每個Observable都取到了值
                break;
            }
            // 執行zipper中傳入的壓縮方法
            v = ObjectHelper.requireNonNull(zipper.apply(os.clone()), "The zipper returned a null value");
            a.onNext(v); //執行下游onNext()
        }
    }
}

簡述工作過程:(第一、第二個觀察者用 first、second代替)

  1. 當first發送數據1時會存儲到ZipObserver的隊列中,此時os[0] = null,從first_observer的隊列中取出1,賦值os[0]=1;
  2. 然後for循環繼續執行,此時os[1]= null,會從second_observer緩存區中獲取數據,如果爲空則跳出內部死循環
  3. 由於外部循環存在方法會繼續循環,內部在從os[0]開始,此時os[0] = 1,second此時也會發送數據4到隊列中
  4. 繼續執行此時os[1]=null,從second的隊列中回去數據賦值os[1] = 4;
  5. 此時emptyCount = 0方法向下執行,調用設置的Function.apply()處理數據(關於Function()這裏採用了嵌套方法)
  6. 調用下游Obserber.onNext()傳遞事件
4.5、onErrorReturn()
@Override
public void subscribeActual(Observer<? super T> t) {
    source.subscribe(new OnErrorReturnObserver<T>(t, valueSupplier)); //創建OnErrorReturnObserver
}
//OnErrorReturnObserver
@Override
public void onError(Throwable t) { //在onError()方法中觸發
    T v;
    v = valueSupplier.apply(t); //(1)在攔截onError時調用設置的方法,生成要發送的數據
    actual.onNext(v); //(2)發送新生成的數據
    actual.onComplete(); 
}

最終創建ObservableOnErrorReturn和OnErrorReturnObserver,在攔截到error後發送特定的值

4.6、retryWhen:重試操作符

創建ObservableRetryWhen實例,在使用retryWhen時會傳入一個返回新的Observable的功能方法,在ObservableRetryWhen內部首先調用方法獲取創建的newObservable,並對newObservable訂閱觀內部察查者Inner.Observer,在外部訂閱觀察者時當發生異常回調onError()時,調用newObservable發送事件,

  1. 如果發送next()觸發內部觀察者onNext(),在onNext()中重新調用外部觀察者訂閱,所有程序會重新try;
  2. 如果發送onError()會直接回到外部Observer的onError()結束程序;
4.7、compose():構成操作符

compose()可以將一系列的相同的操作封裝在一起使用,將功能封裝在ObservableTransformer的實例中,在接口方法中可以對傳入的Observable執行操作然後重新返回,系統會將重新返回的Observable封裝在新的ObservableFromUnsafeSource中繼續執行

  • 創建ObservableTransformer實例對Observable執行統一的操作
public static <T> ObservableTransformer<T, T> rxSchedulerHelper() {
    return new ObservableTransformer<T, T>() {
        @Override
        public ObservableSource<T> apply(Observable<T> upstream) { //對傳入的Observable進行指定線程操作
            return upstream.subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread());
        }
    };
}
  • 使用compose()
Observable.just(1)
        .compose(RxHelper.<Integer>rxSchedulerHelper())
        .subscribe()
//效果等同於
Observable.just(1)
      .subscribeOn(Schedulers.io())
      .observeOn(AndroidSchedulers.mainThread())
      .subscribe();
  • 源碼分析
public final <R> Observable<R> compose(ObservableTransformer<? super T, ? extends R> composer) {
    return wrap(((ObservableTransformer<T, R>) composer.apply(this)); 
}
public static <T> Observable<T> wrap(ObservableSource<T> source) {
    return RxJavaPlugins.onAssembly(new ObservableFromUnsafeSource<T>(source));
}
//ObservableFromUnsafeSource只是作爲了一層中轉站
public final class ObservableFromUnsafeSource<T> extends Observable<T> {
    final ObservableSource<T> source;
    public ObservableFromUnsafeSource(ObservableSource<T> source) {
        this.source = source;
    }
    @Override
    protected void subscribeActual(Observer<? super T> observer) {
        source.subscribe(observer);
    }
}

執行流程如下:

  1. compose()首先執行apply()傳入this,this爲當前的Observable,此處表示爲Observable添加幾個統一的操作符
  2. 使用ObservableFromUnsafeSource封裝包裹source
  3. 在ObservableFromUnsafeSource.subscribeActual()中觸發source.subscribe(observer)完成訂閱;

5、RxJava取消訂閱

  • RxJava取消訂閱(ObservableOnCreate)
@Override
protected void subscribeActual(Observer<? super T> observer) {
    CreateEmitter<T> parent = new CreateEmitter<T>(observer); //(1)創建
    observer.onSubscribe(parent); //回調返回parent
}

由上面的分析知道,在ObservableOnCreate()的subscribeActual()會創建CreateEmitter對象封裝Observer,並回調onSubscribe()返回parent

  1. 調用CreateEmitter.dispose()取消訂閱
@Override
public void dispose() {
    DisposableHelper.dispose(this); //設置解除訂閱標識位
}
@Override
public boolean isDisposed() {
    return DisposableHelper.isDisposed(get()); //獲取是否解除訂閱
}
  1. 在每次發送事件之前都會判斷是否解除訂閱,如果設置瞭解除操作符就會停止事件發送
@Override
public void onNext(T t) {
    if (!isDisposed()) { 
        observer.onNext(t);
    }
}

到此RxJava的基本原理和常用的操作符就分析完了,RxJava的操作符之多功能之強大真的不是幾句話能說完的,但瞭解其內部原理有利於更好的封裝和使用它,除了本篇之外還有關於Schedule的部分也很重要會放在下一篇文章整理。

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