RxJava 2 (二) 基本原理

在上一篇文章中,我基於Obervable類介紹了RxJava的基本用法,再貼一遍代碼

                        Observable.just("hello")      // 代碼1:創建observable
                                .subscribeOn(Schedulers.io())  // 代碼2:用subscribeOn操作符變換observable
                                .observeOn(Schedulers.newThread())  // 代碼3:用observeOn操作符變換observable
                                .subscribe(new Consumer<String>() { // 代碼4:訂閱observer
                                    @Override
                                    public void accept(String s) throws Exception {
                                        System.out.println(s);
                                    }
                                });

還是原來的三段式,創建observable,變換observable,訂閱observer。
上面的4句代碼,我們逐一分析,先看代碼1

    public static <T> Observable<T> just(T item) {
        ObjectHelper.requireNonNull(item, "The item is null");
        return RxJavaPlugins.onAssembly(new ObservableJust<T>(item));
    }

可以看到代碼1會返回一個ObservableJust對象,點進去可以發現它是一個Observable對象,保存有item值。
其中RxJavaPlugins.onAssembly只是一個hook assembly的行爲,可以忽略。

代碼2

    public final Observable<T> subscribeOn(Scheduler scheduler) {
        ObjectHelper.requireNonNull(scheduler, "scheduler is null");
        return RxJavaPlugins.onAssembly(new ObservableSubscribeOn<T>(this, scheduler));
    }

它返回一個ObservableSubscribeOn對象,同樣也是一個Observable對象,然後它有一個source變量保存調用方,即代碼1返回的obverable。

代碼3

    public final Observable<T> observeOn(Scheduler scheduler, boolean delayError, int bufferSize) {
        ObjectHelper.requireNonNull(scheduler, "scheduler is null");
        ObjectHelper.verifyPositive(bufferSize, "bufferSize");
        return RxJavaPlugins.onAssembly(new ObservableObserveOn<T>(this, scheduler, delayError, bufferSize));
    }

它返回一個ObservableOberveOn對象,同樣也是一個Observable對象,然後它有一個source變量保存調用方,即代碼2返回的obverable。

代碼4

    public final Disposable subscribe(Consumer<? super T> onNext) {
        return subscribe(onNext, Functions.ON_ERROR_MISSING, Functions.EMPTY_ACTION, Functions.emptyConsumer());
    }
    public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError,
            Action onComplete, Consumer<? super Disposable> onSubscribe) {
        // 忽略兼容性代碼
        LambdaObserver<T> ls = new LambdaObserver<T>(onNext, onError, onComplete, onSubscribe);

        subscribe(ls);

        return ls;
    }

    // 最終調用到的方法
    public final void subscribe(Observer<? super T> observer) {
        ObjectHelper.requireNonNull(observer, "observer is null");
        try {
            observer = RxJavaPlugins.onSubscribe(this, observer);

            ObjectHelper.requireNonNull(observer, "Plugin returned null Observer");

            subscribeActual(observer);
        } catch (NullPointerException e) { // NOPMD
            throw e;
        } catch (Throwable e) {
            // 忽略部分代碼
            throw npe;
        }
    }

如前面文章所講,訂閱observer最後都會跑到這個subscribe(observer)方法,在一系列訂閱方法中,必要的時候會先構造一個Observer對象,如上述代碼中的LambdaObserver。我們重點看最終調用的這個方法。

可以看到subscribe方法其實就是調用subscribleActual(observer)方法,這是個virtual method,每個Observable的子類都會實現。
這裏我們看一下代碼3返回的ObservableOberveOn類的實現

    @Override
    protected void subscribeActual(Observer<? super T> observer) {
        // scheduler爲當前線程
        if (scheduler instanceof TrampolineScheduler) {
            source.subscribe(observer);
        } else {
            // scheduler爲其它線程
            // 指定scheduler創建worker
            Scheduler.Worker w = scheduler.createWorker();
            source.subscribe(new ObserveOnObserver<T>(observer, w, delayError, bufferSize));
        }
    }

重點是這裏會包裝observer爲OberveOnOberver對象,然後訂閱上游的observable。看上游observable即代碼2返回的ObservableSubscribeOn對象的訂閱實現,同樣是subscribeActual方法

    @Override
    public void subscribeActual(final Observer<? super T> s) {
        final SubscribeOnObserver<T> parent = new SubscribeOnObserver<T>(s);
        // 調用下游observer的onSubscrible
        s.onSubscribe(parent);
        // SubscribeTask爲訂閱上游observable
        parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)));
    }

    final class SubscribeTask implements Runnable {
        private final SubscribeOnObserver<T> parent;

        SubscribeTask(SubscribeOnObserver<T> parent) {
            this.parent = parent;
        }

        @Override
        public void run() {
            source.subscribe(parent);
        }
    }

可以看到,同樣是先包裝來自下游的observer爲SubscribeOnObserver,然後訂閱上游的observable,另外這裏會指定“訂閱上游的observable”在哪個線程執行。

繼續跟蹤看上游observable即代碼1返回的ObservableJust對象的subscribleActual方法

    @Override
    protected void subscribeActual(Observer<? super T> s) {
        ScalarDisposable<T> sd = new ScalarDisposable<T>(s, value);
        s.onSubscribe(sd);
        sd.run();
    }

其中ScalarDisposable的run方法如下

        @Override
        public void run() {
            if (get() == START && compareAndSet(START, ON_NEXT)) {
                observer.onNext(value);
                if (get() == ON_NEXT) {
                    lazySet(ON_COMPLETE);
                    observer.onComplete();
                }
            }
        }

可以看到最上游的observable會先調用observer的onSubscrible方法,然後發射數據,視情況調用observer的onNext, onComplete或者onError方法。

在這之後,各個observer包裝有下游的observer,一般命名爲actual,在收到事件後,同樣會視情況調用actual的各個回調方法。

總結一下數據的流向:
observable創建後可以先不理會它是否發射數據,各種操作符變換僅僅是包裝上游的observable,待執行subscrible時會自下游往上游回溯,層層包裝observer並訂閱上游observable,最終到達最上游的observable,在最上游observable的subscrible方法(實際爲subscribleActual)開始發射數據給observer處理,各observer處理數據後會視情況調用下游observer的各個回調方法。

Created with Raphaël 2.1.0ObservableObservableObserverObserverobservableAsuscribleOnnew ObservableB(observableA)observeOnnew ObservableC(observableB)observablec.subscrible(observerA)new ObserverB(observerA)向上回溯observableB.subscrible(observerB)new ObserverC(observerB)observableA.subscrible(observerC)發射數據ObserverC.onNextObserverB.onNextObserverA.onNext

到這裏RxJava的原理已經講完,各種操作符的作用無非是分析兩點
1. subscrible下游向上游回溯的時候subscribleActual除了包裝observer還做了什麼
2. 最頂層observable發射數據後自上游向下遊observer各自做了什麼

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