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方法

扫描二维码关注公众号,回复: 831292 查看本文章
    @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.0 Observable Observable Observer Observer observableA suscribleOn new ObservableB(observableA) observeOn new ObservableC(observableB) observablec.subscrible(observerA) new ObserverB(observerA) 向上回溯 observableB.subscrible(observerB) new ObserverC(observerB) observableA.subscrible(observerC) 发射数据 ObserverC.onNext ObserverB.onNext ObserverA.onNext

到这里RxJava的原理已经讲完,各种操作符的作用无非是分析两点
1. subscrible下游向上游回溯的时候subscribleActual除了包装observer还做了什么
2. 最顶层observable发射数据后自上游向下游observer各自做了什么

猜你喜欢

转载自blog.csdn.net/w_xue/article/details/77870316