Rxjava2流程初探(二)
目标
- 了解订阅过程中线程切换的时机。
- 了解背压的流程。
subscribeOn与observeOn初探
在阅读本文之前,可以先看看上一篇文章:Rxjava2流程初探
用途
subscribeOn和observeOn都是用于切换线程,但作用范围不一样。observeOn只影响下游的观察者,从observeOn对应的观察者到下一个observeOn调用之前;subscribeOn影响上游的被观察者以及下游的观察者,从subscribeOn对应的被观察者的上一个被观察者开始,一直到上一个subscribeOn对应的被观察者或者下发数据时遇到的第一个observeOn对应的观察者之前的观察者。
源码探究
使用过或者从网上Google过都可知道,subscribeOn多次调用只有在第一次调用才有效果,observeOn每次调用都会使到下游观察者切换到相应的线程。为什么两者会有这区别呢?
先从subscribeOn开始,看看这方法:
public final Observable<T> subscribeOn(Scheduler scheduler) {
ObjectHelper.requireNonNull(scheduler, "scheduler is null");
return RxJavaPlugins.onAssembly(new ObservableSubscribeOn<T>(this, scheduler));
}
创建一个ObservableSubscribeOn的被观察者然后就返回,既然是被观察者,那么订阅之后一定执行subscribeActual这个方法:
@Override
public void subscribeActual(final Observer<? super T> observer) {
final SubscribeOnObserver<T> parent = new SubscribeOnObserver<T>(observer);
observer.onSubscribe(parent);
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);
}
}
SubscribeOnObserver观察者对下游观察者进行了封装,SubscribeTask是一个Runnable,并且引用SubscribeOnObserver。然后使用scheduler把该Runnable放到相应的线程去执行,在SubscribeTask的run方法中,再使用ObservableSubscribeOn的上游观察者source订阅SubscribeOnObserver。
从这可知,subscribeOn发生在从下游被观察者往上逐层订阅的过程中,因此最上游的被观察者只受到最开始的subscribeOn影响。
接着看observeOn,经过几层跳转,最终来到:
public final Observable<T> observeOn(Scheduler scheduler, boolean delayError, int bufferSize) {
ObjectHelper.requireNonNull(scheduler, "scheduler is null");
ObjectHelper.verifyPositive(bufferSize, "bufferSize");
return RxJavaPlugins.onAssembly