rxjava原理面试 scheduler 怎么切换线程


接着上一篇文章<<rxJava和rxAndroid源码解析系列二之observer订阅>>继续说一下线程切换。在上一篇的 <源代码片段15>中可以看出订阅事件以及扔到线程池中进行执行,也就是要订阅的东西已经切换线程了。上篇文章讲到 <源代码片段19>中的代码片段source.subscribe(parent);也就是执行这句话,根据上一篇的关系引用图我们知道source是ObservableOnSubscribe,subscribe是ObservableOnSubscribe的方法,是我们在代码中定义的,代码也就是第一篇文章的下面的代码

subscribe方法不是我们的调度计划嘛,原来如此。parent也就是subscribe方法的参数ObservableEmitter<String> emitter,也就是ObservableCreate的静态内部类CreateEmitter的对象。也就可以这么说我们的计划调度是通过ObservableEmitter进行往下游回调的。

那就看看计划调度onNext,也就是ObservableEmitter.onNext方法。

                                                                                <源代码片段1>

看来又往下游的观察者进行回调,ObservableSubscribeOn.SubscribeOnObserver.onNext(T t)

                                                                                 <源代码片段2>

没做什么操作,继续往下游回调

                                                                          <源代码片段3>

queue是一个队列,t加入这个队列。然后看看schedule();

                                                                         <源代码片段4>

这个worker是谁呢,看过前面两章的朋友知道,这个worker是HandlerWorker的对象,这个worker拥有成员变量handler,这个handler是主线程的。这个this就是ObservableSubscribeOn.SubscribeOnObserver,它也实现了runnable,

                                                                           <源代码片段5>

那我们看看worker.schedule(this);这个方法喽!

                                                                         <源代码片段6>

什么鬼,还要跟踪。

                                                                                           <源代码片段7>

我们来主要看这句话 Message message = Message.obtain(handler, scheduled);handler是主线程的,这种创建message不就是发送给主线程处理的嘛?看来这里已经切换到主线程了!!!(不了解handler、Looper的机制的可以去了解一下)。我这里说一下handler里面有一个处理消息的方法

                                                                          <源代码片段8>

                                                                           <源代码片段9>

到这里我们知道了,message.callback就是ScheduledRunnable ,这个ScheduledRunnable是对ObservableObserveOn.ObserveOnObserver的封装,实际执行的也就是这个run方法,也就是 <源代码片段5>中的代码。那我门就看看这里面怎么执行的。

outputFused默认情况为false,只有再执行requestFusion的时候且满足特定条件才为true.

                                                                        <源代码片段10>

那我们就看看这个drainNormal();

                                                                                   <源代码片段11>

好,到这里已经说完了onNext的回调过程,以及子线程如何切换到主线程的。有兴趣的同学可以看看CreateEmitter.onError和CreateEmitter.onComplete过程。