RxJava2 理解:建厂三部曲

本文记录我对 RxJava2 的理解与思考

文章目录

  • 一、RxJava 三部曲
  • 二、简单的例子-打印字符串
  • 三、复杂的例子-线程切换
      • subscribeOn
      • ObservableSubscribeOn
      • observeOn
  • 四、总结

一、RxJava 三部曲

RxJava 的操作流程可以总结为三部曲:

  • 建厂
  • 签约
  • 开工

二、简单的例子-打印字符串

下面以简单的字符串打印阐述三部曲。

java 实现:

String[] ps = {"p1", "p2", "p3"};
for (String p : ps) {
    System.out.println(p);
}

改为 rxjava 的实现:

Observable.just("p1", "p2", "p3")
.subscribe(new Consumer<String>() {
    @Override
    public void accept(String s) throws Exception {
        System.out.println(s);
    }
});

Observable.just("p1", "p2", "p3"):建厂,这个厂生产"p1"、“p2”、“p3”。
.subscribe(new Consumer()):签约、开工。
签约:跟 Consumer 确定合作关系。
开工:把"p1"、“p2”、"p3"发给 Consumer。

subscribe 内部执行过程:

subscribe(consumer)//签约
	-->subscribe(observer)//签约
		-->subscribeActual(observer)//开工
			-->observer.onNext("p1")
				-->consumer.accept("p1")

其实就是 Observable 持有 Observer 的引用,再在合适的时机调用 Observer 的方法。

上面使用 just 的 RxJava 写法比 Java 写法多了一点,但其实已经是一种封装,最原始的 RxJava 写法要更多:

Observable<String> observable = new Observable<String>() {
    @Override
    protected void subscribeActual(Observer<? super String> observer) {
        String[] ps = {"p1", "p2", "p3"};
        for (String p : ps) {
            observer.onNext(p);
        }
        observer.onComplete();
    }
};

Observer<String> observer = new Observer<String>() {
    @Override
    public void onSubscribe(Disposable d) {

    }

    @Override
    public void onNext(String s) {
        System.out.println(s);
    }

    @Override
    public void onError(Throwable e) {

    }

    @Override
    public void onComplete() {

    }
};

observable.subscribe(observer);

原始代码同样符合三部曲:

  • 建厂:创建 Observable 对象。
  • 签约:observable.subscribe。
  • 开工:observer.onNext(p)。

三、复杂的例子-线程切换

下面以线程切换阐述三部曲。

java 实现:

new Thread(new Runnable() {
    @Override
    public void run() {
        String[] ps = {"p1", "p2", "p3"};
        for (String p : ps) {
            System.out.println(p);
        }
    }
}).start();

rxjava 实现:

Observable<String> observable = new Observable<String>() {
    @Override
    protected void subscribeActual(Observer<? super String> observer) {
        String[] ps = {"p1", "p2", "p3"};
        for (String p : ps) {
            observer.onNext(p);
        }
        observer.onComplete();
    }
};

Observer<String> observer = new Observer<String>() {
    @Override
    public void onSubscribe(Disposable d) {

    }

    @Override
    public void onNext(String s) {
        System.out.println(s);
    }

    @Override
    public void onError(Throwable e) {

    }

    @Override
    public void onComplete() {

    }
};

observable
    .subscribeOn(Schedulers.io())
    .subscribe(observer);

如何实现的,关键在这里。

observable
    .subscribeOn(Schedulers.io())
    .subscribe(consumer);

subscribeOn

返回一个 ObservableSubscribeOn,它是一个 Observable(一个加工地)。

ObservableSubscribeOn

它继承了 AbstractObservableWithUpstream,即有上游的 Observable(加工地的基类)。

它有一个 Scheduler 对象(关于 Scheduler,可见RxJava2:Scheduler 详解)。

一个 Observable 最关键的方法就是它的 subscribeActual,我们看下 ObservableSubscribeOn 的 subscribeActual 方法:

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

    s.onSubscribe(parent);

    parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)));
}

一步步分析:

parent = new SubscribeOnObserver(s)

里面生成了一个 SubscribeOnObserver,它是一个 Observer(加工地厂长),内部还有一个 Observe(客户),相当于它自己也是个客户(相对上游而言)。

同时它也是一个 Disposable(可以提供给对方合同)。

同时它还有一个 Disposable 对象(可以接受对方的合同)。

s.onSubscribe(parent)

客户 s 接受了加工地厂长 parent 的合同,客户 s 可以持有这份合同(disposable),并单方面撕毁合同(disposable.dispose(),相当于 removeCallback、unregisterListener)。

parent.setDisposable()

加工地厂长来制定自己提供的合同内容。合同的内容是 scheduler.scheduleDirect(new SubscribeTask(parent))

scheduler.scheduleDirect(new SubscribeTask(parent))

这里是逻辑的重点。 在这里,scheduler 会按自己的策略执行 SubscribeTask,SubscribeTask 是一个 runnable,run 里面就是 source.subscribe(parent),source 是加工地的上游,parent 就是厂长自己,所以厂长在这里与上游签约。

即 subscribeOn 的厂长在跟给下游签约时,提供了一份合同,合同的内容是:厂长会与上游在 scheduler 提供的线程中签约。

如果原厂地没有特殊处理,它会在跟客户(或是加工地厂长)在签约的线程开工。所以,当使用了多个 subscribeOn() 的时候,只有第一个 subscribeOn() 起作用。因为只有离生产地最近的那个加工地厂长能决定它的上游——生产地的开工线程。

这也解释了为什么 subscribeOn 需要给下游提供一份合同,因为它会影响上游的生产过程,下游可以用合同去停止整个活动。

observeOn

再看下 observeOn,会生成一个 ObservableObserveOn,它的 subscribeActual:

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

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

source 是上游,observeOn 自己直接跟上游签约,没有执行特殊操作,也没有提供给下游合同。

因为没有执行特殊操作,所有不会影响上游的生产过程,所有也不用取消,所有也不用给下游合同。它会在收到上游的合同时把它转交给下游(自己的 onSubscribe() 被调用时调用下游的 onSubscribe())。

它的作用主要在 ObserveOnObserver:

@Override
public void onNext(T t) {
    if (done) {
        return;
    }

    if (sourceMode != QueueDisposable.ASYNC) {
        queue.offer(t);
    }
    schedule();
}

ObserveOnObserver 收到上游发送的产品,执行 schedule(),把产品提供给下游。

observeOn() 能够多次调用,就是因为 它的作用在于加工,加工的内容就是:在 Scheduler 提供的线程中把产品提供给下游。至于 subscribeOn 的加工内容,当然是没有加工,直接提供给下游。

再回顾一下:

  • subscribeOn 的线程切换发生在签约时
  • observeOn 的线程切换发生在加工时

四、总结

箭头的意义是持有:
RxJava2 理解:建厂三部曲_第1张图片

  • 创建生产地 able1
  • 创建加工地 able2(able2)、er2
  • 创建加工地 able3(able2)、er3
  • 创建客户 er4
  • 签订合同 able3.subscribe(er4)
  • 签订合同 able2.subscribe(er3)
  • 签订合同 able1.subscribe(er2)
  • 开始生产产品并传给下一个加工地 er2.onNext()
  • 开始加工产品并传给下一个加工地 er3.onNext()
  • 传给客户 er4.onNext()

你可能感兴趣的:(Android,理解,RxJava,源码)