Rxjava(4) 线程切换 - AndroidSchedulers.mainThread()

4,200 阅读3分钟

observable的.observeOn(AndroidSchedulers.mainThread())方法指定最后的结果处于哪个线程中,是通过handler发送消息到主线中的MainLooper中。为Message的callback设置对象。在handler的dispatchMessage方法中会进行拦截,不会调用handler 的handleMessage方法。

流程图

以一下简单示例看下执行过程

        Observable.just("")
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<String>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                    }
                    @Override
                    public void onNext(String s) {
                    }
                    @Override
                    public void onError(Throwable e) {
                    }
                    @Override
                    public void onComplete() {
                    }
                });

1, 创建ObservableObserveOn对上层的onservable进行包装,并保存传过来的主线程的Scheduler

    public final Observable<T> observeOn(Scheduler scheduler) {
        return observeOn(scheduler, false, bufferSize());
    }
    
    public final Observable<T> observeOn(Scheduler scheduler, boolean delayError, int bufferSize) {
        ObjectHelper.requireNonNull(scheduler, "scheduler is null");
        ObjectHelper.verifyPositive(bufferSize, "bufferSize");
        return RxJavaPlugins.onAssembly(new ObservableObserveOn<T>(this, scheduler, delayError, bufferSize));
    }

2, 执行到ObservableObserveOn的subscribeActual方法,参数的Observer是最后订阅的观察者。在这里有1个重点,就是创建worker的过程。scheduler是传过来的AndroidSchedulers.mainThread()。

    @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));
        }
    }

3, AndroidSchedulers对外提供了static的mainThread方法,返回Scheduler对象。创建的方式是通过Callable接口(扩展的rxjava中的功能,向JakeWharton致敬)。这里有个很有趣的地方,就是HandlerScheduler的创建方式。

public final class AndroidSchedulers {

// 单利设计模式
    private static final class MainHolder {
        static final Scheduler DEFAULT = new HandlerScheduler(new Handler(Looper.getMainLooper()));
    }

    private static final Scheduler MAIN_THREAD = RxAndroidPlugins.initMainThreadScheduler(
            new Callable<Scheduler>() {
                @Override public Scheduler call() throws Exception {
                    return MainHolder.DEFAULT;
                }
            });
 
    public static Scheduler mainThread() {
        return RxAndroidPlugins.onMainThreadScheduler(MAIN_THREAD);
    }

 
 
}

4, 调用HandlerScheduler 的createWorker,返回HandlerWorker对象。HandlerWorker实现Scheduler的抽象的Worker类。

   @Override
    public Worker createWorker() {
        return new HandlerWorker(handler);
    }

5, 然后执行到 source.subscribe(new ObserveOnObserver(observer, w, delayError, bufferSize));这个语句。source是上层的observable,给它添加注册观察者。

以just("")的被观察者对象为例,会先执行第2条语句onSubscribe。然后执行run方法(onNext方法)。

    protected void subscribeActual(Observer<? super T> s) {
        ScalarDisposable<T> sd = new ScalarDisposable<T>(s, value);
        s.onSubscribe(sd);
        sd.run();
    }

6, 调用ObserveOnObserver的onSubscribe方法。这个方法中主要就是给queue进行赋值/初始化。然后调用下层的observer的onSubscribe方法。

    @Override
        public void onSubscribe(Disposable s) {
            if (DisposableHelper.validate(this.s, s)) {
                this.s = s;
                if (s instanceof QueueDisposable) {
                    @SuppressWarnings("unchecked")
                    QueueDisposable<T> qd = (QueueDisposable<T>) s;

                    int m = qd.requestFusion(QueueDisposable.ANY | QueueDisposable.BOUNDARY);

                    if (m == QueueDisposable.SYNC) {
                        sourceMode = m;
                        queue = qd;
                        done = true;
                        actual.onSubscribe(this);
                        schedule();
                        return;
                    }
                    if (m == QueueDisposable.ASYNC) {
                        sourceMode = m;
                        queue = qd;
                        actual.onSubscribe(this);
                        return;
                    }
                }

                queue = new SpscLinkedArrayQueue<T>(bufferSize);

                actual.onSubscribe(this);
            }
        }

7, 调用ObserveOnObserver的onNext方法,将流中的数据t存入到queue中。调用schedule方法。

        @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);
            }
        }

8, 调用HandlerWorker的schedule方法传入this,那肯定是实现了runable接口。

    public Disposable schedule(Runnable run, long delay, TimeUnit unit) {
            run = RxJavaPlugins.onSchedule(run);
            ScheduledRunnable scheduled = new ScheduledRunnable(handler, run);
            //将runbale 对象为message中的callback变量进行赋值
            Message message = Message.obtain(handler, scheduled);
            message.obj = this;  
           // 将message发送到主线程的looper中
            handler.sendMessageDelayed(message, Math.max(0L, unit.toMillis(delay)));
             if (disposed) {
                handler.removeCallbacks(scheduled);
                return Disposables.disposed();
            }
            return scheduled;
        }

9, 在主线程中会执行ObserveOnObserver的run方法。

      @Override
        public void run() {
            if (outputFused) { 
                drainFused();// 融合
            } else {
                drainNormal();// 正常
            }
        }

10, 以 drainNormal 为例,将之前保存到queue中的值取出来,然后调用下层的observer对象的onNext方法,将值传进去。

 void drainNormal() {
            final SimpleQueue<T> q = queue;
            final Observer<? super T> a = actual;
            for (;;) {
                if (checkTerminated(done, q.isEmpty(), a)) {
                    return;
                }
                for (;;) {
                    T v;
                    try {
                        v = q.poll();
                    } catch (Throwable ex) {   
                    }
                    a.onNext(v);
                }

                
            }
 }