Rxjava 有两个链:1.自下向上调用Observable的subscribe方法,2.自上向下调用Observer的onNext方法。自下向上到ObservableOnSubscribe的subscribe方法,然后开始自上向下。
线程切换是用subscribeOn和observeOn两个方法,它们生成的Observable对象都有Scheduler,Scheduler就是用来帮它们实现线程切换。
了解这两个方法之前介绍下Shedulder
既然要实现线程切换,就一定有地方生成线程,并把需要线程运行的代码封装到Runnable中,让线程运行Runnable,这些都是由Shedulder完成的。
以Schedulers.newThread()为例 介绍下Scheduler,Schedulers.newThread()得到的是NewThreadScheduler。
public Disposable scheduleDirect(@NonNull Runnable run, long delay, @NonNull TimeUnit unit) { //生成worker,这里的实现类是NewThreadWorker ,里面有个ScheduledExecutorService线程池 final Worker w = createWorker(); final Runnable decoratedRun = RxJavaPlugins.onSchedule(run); DisposeTask task = new DisposeTask(decoratedRun, w); //把Runnable 放到线程池执行 w.schedule(task, delay, unit); return task; }
1.subscribeOn是在自下向上调用subscribe过程中,用scheduler把接下来往上调用的代码放到一个新的线程中,实现线程切换。
一次subscribeOn,表示切换一次线程,如果有多个subscribeOn,再向上不断调用的过程过实现多次线程切换, 只有最靠近Observable.create的subscribeOn,才决定最后ObservableOnSubscribe.subscribe在那个线程执行。
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))); }
//把source.subscribe(parent)的调用封装成Runnable
final class SubscribeTask implements Runnable { private final SubscribeOnObserver<T> parent; SubscribeTask(SubscribeOnObserver<T> parent) { this.parent = parent; } @Override public void run() { source.subscribe(parent); } }
2.observeOn是在Observer自上向下,调用onNext时把接下来调用onNext放到一个子线程执行,所以observeOn影响后面的代码。
observeOn方法生成ObserveOnObserver对象,以下是简要代码
static final class ObserveOnObserver<T> extends BasicIntQueueDisposable<T> implements Observer<T>, Runnable{ @Override public void onNext(T t) { if (done) { return; } if (sourceMode != QueueDisposable.ASYNC) { queue.offer(t); } schedule(); }
void schedule() { if (getAndIncrement() == 0) { worker.schedule(this); } } @Override public void run() { if (outputFused) { drainFused(); } else { drainNormal();//最终 a.onNext(v); } } }
3.切换到android 中的主线程 ,AndroidSchedulers.mainThread()生成HandlerScheduler,主要原理还是使用了Android的handler,实现线程切换
// Looper.getMainLooper()表示handler 会在主线程执行 private static final class MainHolder { static final Scheduler DEFAULT = new HandlerScheduler(new Handler(Looper.getMainLooper()), false); }
final class HandlerScheduler extends Scheduler{
@Override public Disposable scheduleDirect(Runnable run, long delay, TimeUnit unit) { if (run == null) throw new NullPointerException("run == null"); if (unit == null) throw new NullPointerException("unit == null"); run = RxJavaPlugins.onSchedule(run); ScheduledRunnable scheduled = new ScheduledRunnable(handler, run); //把Runnable发送到主线程 handler.postDelayed(scheduled, unit.toMillis(delay)); return scheduled; }
}