RxJava执行流程

核心问题:
- 为甚是被观察者订阅观察者
- RxJava执行的流程

为甚是被观察者订阅观察者

Observable.subscribe(Observer); 从字面上的理解是被观察者订阅观察者,比如报纸订阅了读者。但从开发者的角度来理解,就很正常 了。

RxJava这样设置的目的是为了流式Api的设计,还有就是Android中的观察者模式都是这样的写法,比如View.setOnClickListener(OnClickListener) : View就是被观察者,OnClickListener是观察者,他们通过setOnClickListener形成订阅关系。 一旦被观察者发生了什么事情(事件),就需要告知观察者,然后观察者会做出相应的措施。

RxJava执行的流程

从一个简单的示例代码说起:

 Observable.create(new ObservableOnSubscribe() {
            @Override
            public void subscribe(ObservableEmitter e) throws Exception {
                e.onNext(1);
                e.onNext(2);
                e.onComplete();
            }
        })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer() {
                    private Disposable mD = null;

                    @Override
                    public void onSubscribe(Disposable d) {
                        mD = d;
                    }

                    @Override
                    public void onNext(Integer value) {
                        if (1 == value) {
                            mD.dispose();
                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                        KLog.d("e:" + e.toString());
                    }

                    @Override
                    public void onComplete() {
                        KLog.d("onComplete");
                    }
                });

按照自上而下的顺序,开始吧

Observable.create(ObservableOnSubscribe source)

   public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
        ObjectHelper.requireNonNull(source, "source is null");
        return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
    }

流程的第一步,创建了两个对象:ObservableOnSubscribe 和 ObservableCreate 。

ObservableCreate

public final class ObservableCreate<T> extends Observable<T> {
    final ObservableOnSubscribe source;

    public ObservableCreate(ObservableOnSubscribe source) {
        this.source = source;
    }

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

        try {
            source.subscribe(parent);
        } catch (Throwable ex) {
            Exceptions.throwIfFatal(ex);
            parent.onError(ex);
        }
    }

    //省略其他代码

}

ObservableCreate 继承Observable,在构造函数中保存了上一级创建的 ObservableOnSubscribe 对象的引用。

public abstract class Observable<T> implements ObservableSource<T>{...}
public interface ObservableSource {

    void subscribe(Observer observer);
}

上面的2段源码清楚的看到,Observable 是一个抽象类,是 ObservableSource 的实现类,而 ObservableSource 类是一个接口,它表示事件源。内部只有一个方法 subscribe 该方法表示通过 Observer 订阅当前的事件源。那么事件发布的事件,在 Observer 订阅者中就会被收到。了解了 Observable 的顶层接口之后,我们就知道该体系最重要的一个功能那就是 subscribe 方法了,因此我们就重点关注子类的 subscribe 方法。

现在,把视角转到Observable的subscribe()方法来,看看它做了什么处理。

 public final void subscribe(Observersuper 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) {
            Exceptions.throwIfFatal(e);
            // can't call onError because no way to know if a Disposable has been set or not
            // can't call onSubscribe because the call might have set a Subscription already
            RxJavaPlugins.onError(e);

            NullPointerException npe = new NullPointerException("Actually not, but can't throw other exceptions due to RS");
            npe.initCause(e);
            throw npe;
        }
    }


     protected abstract void subscribeActual(Observersuper T> observer);

他把observer订阅者传递给subscribeActual(Observer observer)抽象方法,这意味着所有Observable的子类,我们只要关心 subscribeActual(observer); 这个方法就好的。

好的,那么我们就回到最开始的ObservableCreate,去看看他在subscribeActual()做了什么

   @Override
    protected void subscribeActual(Observersuper T> observer) {
        CreateEmitter parent = new CreateEmitter(observer);
        observer.onSubscribe(parent);

        try {
            source.subscribe(parent);
        } catch (Throwable ex) {
            Exceptions.throwIfFatal(ex);
            parent.onError(ex);
        }
    }

在上面的代码里面,先是创建了一个发射器CreateEmitter,然后回调给 observer#onSubscribe() ,最后是通知上一级的Observable(也就是代码里的source)你可以发送事件了。这边不太了解RxJava可能有疑问我为什么这么下定论?因为事件是在被观察者“订阅”观察者时后才发送的!!!

subscribeOn(Schedulers.io())

这个方法的作用是让上游事件切换线程的,不管它在整个流中使用了几次,只有第一次是有效的。why? 先把这个疑问放下,后面看看流程图就应该明白了。

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

public final class ObservableSubscribeOn<T> extends AbstractObservableWithUpstream<T, T> {
    final Scheduler scheduler;

    public ObservableSubscribeOn(ObservableSource source, Scheduler scheduler) {
        super(source);
        this.scheduler = scheduler;
    }

    @Override
    public void subscribeActual(final Observer super T> s) {
        final SubscribeOnObserver parent = new SubscribeOnObserver(s);

        s.onSubscribe(parent);

        parent.setDisposable(scheduler.scheduleDirect(new Runnable() {
            @Override
            public void run() {
                source.subscribe(parent);
            }
        }));
    }
    //省略部分代码

}

是不是很熟悉,因为AbstractObservableWithUpstream也是继承自Observable。subscribeActual()方法里执行的也是相似的逻辑,只不过是多了scheduler线程相关的逻辑,这里先不进行详细分析。

abstract class AbstractObservableWithUpstream<T, U> extends Observable<U> implements HasUpstreamObservableSource<T> {

    /** The source consumable Observable. */
    protected final ObservableSource source;

    /**
     * Constructs the ObservableSource with the given consumable.
     * @param source the consumable Observable
     */
    AbstractObservableWithUpstream(ObservableSource source) {
        this.source = source;
    }

    @Override
    public final ObservableSource source() {
        return source;
    }

}

这个抽象类也是保存了上一个Observable的引用。

observeOn(AndroidSchedulers.mainThread())

我猜这边应该是相似的代码。

public final class ObservableObserveOn<T> extends AbstractObservableWithUpstream<T, T> {
    final Scheduler scheduler;
    final boolean delayError;
    final int bufferSize;
    public ObservableObserveOn(ObservableSource source, Scheduler scheduler, boolean delayError, int bufferSize) {
        super(source);
        this.scheduler = scheduler;
        this.delayError = delayError;
        this.bufferSize = bufferSize;
    }

    @Override
    protected void subscribeActual(Observersuper T> observer) {
        if (scheduler instanceof TrampolineScheduler) {
            source.subscribe(observer);
        } else {
            Scheduler.Worker w = scheduler.createWorker();

            source.subscribe(new ObserveOnObserver(observer, w, delayError, bufferSize));
        }
    }

    //省略相关代码
}

果不其然,就不赘述了。

subscribe(Observer observer)

subscribe后,被观察者(Observable)一旦有发射什么事件,观察者(Observer)都可以接收事件。

总结

过程:断点调试,绘制流程图

还记得在介绍 #subscribeOn(Schedule)方法提出的那个问题?

无论我们在整个上游的事件流中使用了多少次#subscribeOn(Schedule)变换线程,只有第一次设置的有效。看了上面的流程图,相信应该明白了吧。

下一篇,讲述RxJava线程切换原理

你可能感兴趣的:(Android必备技,RxJava)