RxJava的线程切换实质就是把不同的处理事务交由不同的线程去进行处理。代码流程看起来热仍然是像Observable.create(observableOnSubscribe).subscribe(observer)这种基本格式。那么线程切换流程在源码上是怎么做到的呢?另外,多个subscribeOn对应不同线程模型时,是都生效还是只对第一个线程有效,以及observeOn对应不同线程模型时,又是否各自在对应的线程生效,接下来,我们在分析源码并简化各步骤中给出答案:
Observable
.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> observableEmitter) throws Exception {
observableEmitter.onNext("hello world");
Log.d("RxJava2", "This msg from work thread :" + Thread.currentThread().getName());
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new io.reactivex.Observer<String>() {
@Override
public void onSubscribe(Disposable disposable) {
}
@Override
public void onNext(String s) {
Log.d("RXJava2", "welcome: " + s);
Log.d("RxJava2", "This msg from work thread :" + Thread.currentThread().getName());
}
@Override
public void onError(Throwable throwable) {
}
@Override
public void onComplete() {
}
});
step1 这一步上文已经分析过了,既返回new ObservableCreate(source)
Observable
.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> observableEmitter) throws Exception {
observableEmitter.onNext("hello world");
Log.d("RxJava2", "This msg from work thread :" + Thread.currentThread().getName());
}
})
step2 在step1的结果上,调用
new ObservableCreate(source).subscribeOn(Schedulers.io()
那么返回ObservableSubscribeOn的实例,这里this为step1的结果ObservableCreate实例。
new ObservableSubscribeOn(this, scheduler)
ObservableSubscribeOn继承AbstractObservableWithUpstream,而AbstractObservableWithUpstream继承Observable,因此,正如上文所说的,都为Observable的变种(具体子类实现)。既然是继承关系,那么主要就在于subscribeActual方法,从上文知道,所有进行订阅之后,都会走到具体Observable实例的subscribeActual方法中,这里在后面步骤中再具体分析subscribeActual方法;
step3 在step2的结果下继续执行:
new ObservableSubscribeOn(this, scheduler)
.observeOn(AndroidSchedulers.mainThread())
那么返回的结果为:
new ObservableObserveOn(this, scheduler, delayError, bufferSize)
其中this为ObservableSubscribeOn实例,同样deObservableObserveOn继承AbstractObservableWithUpstream,如step2分析,同样在订阅的过程中会走到subscribeActual方法。这里在后面步骤中分析。
step4 在step3的结果下继续执行,则如下代码所示:
new ObservableObserveOn(this, scheduler, delayError, bufferSize)
.subscribe(new io.reactivex.Observer<String>() {
@Override
public void onSubscribe(Disposable disposable) {
}
@Override
public void onNext(String s) {
Log.d("RXJava2", "welcome: " + s);
Log.d("RxJava2", "This msg from work thread :" + Thread.currentThread().getName());
}
@Override
public void onError(Throwable throwable) {
}
@Override
public void onComplete() {
}
});
那么执行这一步之后,既进行了订阅之后,我们找到ObservableObserveOn的subscribe方法,由继承关系,实际还是走到父类Observable的subscribe方法中,同上文,如下:
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");
this.subscribeActual(observer);
} catch (NullPointerException var4) {
throw var4;
} catch (Throwable var5) {
Exceptions.throwIfFatal(var5);
RxJavaPlugins.onError(var5);
NullPointerException npe = new NullPointerException("Actually not, but can't throw other exceptions due to RS");
npe.initCause(var5);
throw npe;
}
}
这时走到subscribeActual方法中,subscribeActual是个抽象方法,具体在子类中实现,这里子类为ObservableObserveOn,进入ObservableObserveOn的子类的subscribeActual方法中,如下:
protected void subscribeActual(Observer<? super T> observer) {
if (this.scheduler instanceof TrampolineScheduler) {
this.source.subscribe(observer);
} else {
Worker w = this.scheduler.createWorker();
this.source.subscribe(new ObservableObserveOn.ObserveOnObserver(observer, w, this.delayError, this.bufferSize));
}
}
我们看到,又调用一个形如this.source.subscribe(observer)的语句,这里的source是什么呢,我们可以套observable.subscribe(observer),这里的source肯定是Observable实例,source是在ObservableObserveOn的构造函数赋值的,而ObservableObserveOn在step3中进行初始化,即,这里的this我们在上面已经分析了,实际就是上一个Observable,即ObservableSubscribeOn。
new ObservableObserveOn(this, scheduler, delayError, bufferSize)
从这里我们可以知道,这里就是类似装饰着模式,装饰者模式的作用就是动态的将责任附加到对象上,提供了比继承更加弹性的替代方案,通过组合的方式实现。
回到这一步来,现在进行到
this.source.subscribe(new ObservableObserveOn.ObserveOnObserver(observer, w, this.delayError, this.bufferSize));
通过上面分析,实际走到ObservableSubscribeOn的subscribe方法中,注意,这里的Observer也进行了一层包装,一开始在订阅的时候,是最简单的observer,而到这里的时候已经进行了一层封装,如下:
new ObservableObserveOn.ObserveOnObserver(observer, w, this.delayError, this.bufferSize)
为ObservableObserveOn.ObserveOnObserver实例,实际上ObserveOnObserver实现了Observer接口。也就是说,Observable从上往下进行了装饰者模式组合封装,而Observer从下往上进行了装饰者模式组合封装,当subscribe的时候,从Observable的最外层开始进行订阅,然后一层层进行subscribeActual的时候,又一层层的组合封装了observer,到达observable最基层的时候,发射器开始发射拿着最外层的observer开始进行一层层的揭开发送事件,最后就到了observer最基层。这部分具体会在下面以图文的形式展开。
现在,就走到ObservableSubscribeOn的subscribeActual方法, 如下:
public void subscribeActual(Observer<? super T> s) {
ObservableSubscribeOn.SubscribeOnObserver<T> parent = new ObservableSubscribeOn.SubscribeOnObserver(s);
s.onSubscribe(parent);
parent.setDisposable(this.scheduler.scheduleDirect(new ObservableSubscribeOn.SubscribeTask(parent)));
}
subscribeActual看起来没有直接调用形如this.source.subscribe(observer)语句,但肯定有相关的。
首先和上面分析的一样,对observer入参进行了一层组合封装,为SubscribeOnObserver实例,然后调用parent.setDisposable方法,主要看
this.scheduler.scheduleDirect(new ObservableSubscribeOn.SubscribeTask(parent));
根据例子,scheduler即为例子中的Schedulers.io(), 即为IoScheduler实例,进入scheduleDirect方法,该方法在父类Scheduler中,会执行如下方法
public Disposable scheduleDirect(@NonNull Runnable run, long delay, @NonNull TimeUnit unit) {
Scheduler.Worker w = this.createWorker();
Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
Scheduler.DisposeTask task = new Scheduler.DisposeTask(decoratedRun, w);
w.schedule(task, delay, unit);
return task;
}
这里run即为ObservableSubscribeOn.SubscribeTask实例,调用this.createWorker()进入到IoScheduler的具体方法实现中去
public Worker createWorker() {
return new IoScheduler.EventLoopWorker((IoScheduler.CachedWorkerPool)this.pool.get());
}
接着执行w.schedule方法,这里的w即为上面的EventLoopWorker实例,方法中代码如下:
public Disposable schedule(@NonNull Runnable action, long delayTime, @NonNull TimeUnit unit) {
return (Disposable)(this.disposed ? EmptyDisposable.INSTANCE : this.poolWorker.scheduleActual(action, delayTime, unit, this.timed));
}
this.poolWorker.scheduleActual的实现如下:
public ScheduledRunnable scheduleActual(Runnable run, long delayTime, @NonNull TimeUnit unit, @Nullable DisposableContainer parent) {
Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
ScheduledRunnable sr = new ScheduledRunnable(decoratedRun, parent);
if (parent != null && !parent.add(sr)) {
return sr;
} else {
try {
Object f;
if (delayTime <= 0L) {
f = this.executor.submit(sr);
} else {
f = this.executor.schedule(sr, delayTime, unit);
}
sr.setFuture((Future)f);
} catch (RejectedExecutionException var10) {
if (parent != null) {
parent.remove(sr);
}
RxJavaPlugins.onError(var10);
}
return sr;
}
}
最后执行了ScheduledRunnable,而ScheduledRunnable的run方法中执行了Scheduler.DisposeTask实例的run方法,而DisposeTask的run方法又执行了new ObservableSubscribeOn.SubscribeTask实例的run方法,其实现如下:
ObservableSubscribeOn.this.source.subscribe(this.parent);
是不是饶了一大圈,又回到了我们熟悉的this.source.subscribe(observer),这也验证了我们猜测的,回顾一下刚才一路分析下来的,例子中调用了subscribeOn方法,那么在subscribe的过程中,会创建相应的线程,那么谁会在这个线程做些操作呢?
我们继续上面分析到this.source.subscribe(observer),这里ObservableSubscribeOn.this.source即为例子中ObservableCreate,这时就进入到ObservableCreate的subscribeActual方法,然后执行this.source.subscribe(observer),这里的source即为例子中ObservableOnSubscribe的实例,终于,我们要在ObservableOnSubscribe执行subscribe方法了,这里是最基层的,那么执行subscribe的方法是在哪个线程执行的呢?还记得我们前面分析的创建了线程并在线程中执行了run方法,而run方法里面最终就进入到最基层的ObservableOnSubscribe的suscribe方法中来。因此,我们通过上面的分析,可以得出,无论例子中进行了多少次subscribeOn方法,最终执行的subscrbe方法是运行在第一次subscribeOn指定的线程中。
step5 进到到ObservableOnSubscribe的subscrbe方法之后,就要开始通过发射器发射事件了。而我们这里的发射就是组合了observer一层层封装而来。我们再一步步分析this.source.subcribe(observer)已经分析了,那么发射器的发射流程如下所示:
observableEmitter.onNext("hello world") ---> ObservableSubscribeOn.SubscribeOnObserver.onNext("hello world")---> ObservableObserveOn.ObserveOnObserver.onNext("hello word")--->new Observer("hello word")
这里分析下调用ObservableObserveOn.ObserveOnObserver.onNext("hello word")方法之后,是怎么切换到main线程的。ObserveOnObserver的onNext方法如下:
public void onNext(T t) {
if (!this.done) {
if (this.sourceMode != 2) {
this.queue.offer(t);
}
this.schedule();
}
}
void schedule() {
if (this.getAndIncrement() == 0) {
this.worker.schedule(this);
}
}
既进入到worker的schedule方法中,例子中对应的Scheduler为HandlerScheduler,那么对应的worker为HandlerWork,同样的,进入schedule方法中,如下:
@Override
public Disposable schedule(Runnable run, long delay, TimeUnit unit) {
if (run == null) throw new NullPointerException("run == null");
if (unit == null) throw new NullPointerException("unit == null");
if (disposed) {
return Disposables.disposed();
}
run = RxJavaPlugins.onSchedule(run);
ScheduledRunnable scheduled = new ScheduledRunnable(handler, run);
Message message = Message.obtain(handler, scheduled);
message.obj = this; // Used as token for batch disposal of this worker's runnables.
handler.sendMessageDelayed(message, unit.toMillis(delay));
// Re-check disposed state for removing in case we were racing a call to dispose().
if (disposed) {
handler.removeCallbacks(scheduled);
return Disposables.disposed();
}
return scheduled;
}
既然是线程执行方法,找到某个run方法,这个run方法为ObserveOnObserver本身
。最终在HandlerScheduler中通过消息机制把执行ObserveOnObserver的run方法,
public void run() {
if (this.outputFused) {
this.drainFused();
} else {
this.drainNormal();
}
}
最终就会执行observer.onNext()。
上面即为RxJava线程的切换过程,不管怎么变换,只要认准observable.subscribe(observer)即可,万变不离其宗。最后补充两张图,可以形象说明这种流式过程是怎么进行的: