RxJava2 (四)切換UI主線程源碼閱讀

RxJava2 (一)訂閱流程源碼閱讀
RxJava2 (二)取消訂閱流程 dispose( ) 源碼閱讀
RxJava2 (三)線程切換源碼閱讀
RxJava2 (四)切換UI主線程源碼閱讀
RxJava2 (五)just操作符源碼閱讀
RxJava2 (六)map操作符源碼閱讀

依賴
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
implementation 'io.reactivex.rxjava2:rxjava:2.x.x'
代碼示例
Observable.create(new ObservableOnSubscribe<Integer>() {
    @Override
    public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
        System.out.println("被觀察者發射數據線程: " + Thread.currentThread().getId());
        emitter.onNext(100);
    }
})
        .subscribeOn(Schedulers.io()) // 被觀察者發射消息從io線程
        .observeOn(AndroidSchedulers.mainThread()) // 觀察者接收消息後在AndroidSchedulers.mainThread()新線程中處理
        .subscribe(new Observer<Integer>() {
            @Override
            public void onSubscribe(Disposable d) {
                System.out.println("onSubscribe");
            }
            @Override
            public void onNext(Integer integer) {
                System.out.println("onNext: " + integer);
                System.out.println("觀察者接收數據線程: " + Thread.currentThread().getId());
            }
            @Override
            public void onError(Throwable e) {
                System.out.println("onError");
            }
            @Override
            public void onComplete() {
                System.out.println("onComplete");
            }
        });
.observeOn(AndroidSchedulers.mainThread())
  • AndroidSchedulers該類是在RxAndroid庫中
  • RxJava2線程切換原理是通過將被觀察者發射數據與觀察者接收數據的邏輯放在不同的Scheduler創建的線程池中去處理,從而達到切換線程的操作.
  • .observeOn(AndroidSchedulers.mainThread())就是將觀察者接收數據的邏輯由UI線程處理.
  • 下面開始分析觀察者接收數據的邏輯怎麼放入UI線程中處理,完整的切換線程源碼分析可以看這裏
public abstract class Observable<T> implements ObservableSource<T> {
    // 此時observeOn()方法是由ObservableSubscribeOn對象調用的.
    // AndroidSchedulers.mainThread()得到HandlerScheduler對象,通過參數傳入observeOn()方法中
    public final Observable<T> observeOn(Scheduler scheduler) {
        return observeOn(scheduler, false, bufferSize());
    }
    public final Observable<T> observeOn(Scheduler scheduler, boolean delayError, int bufferSize) {
        // 創建一個ObservableObserveOn對象,最終observeOn()方法返回該對象
        // this:會使ObservableObserveOn對象中持有ObservableSubscribeOn對象引用.
        // scheduler:爲HandlerScheduler對象
        return RxJavaPlugins.onAssembly(new ObservableObserveOn<T>(this, scheduler, delayError, bufferSize));
    }
}
.subscribe()
  • observeOn()最終返回ObservableObserveOn對象,由該對象調用.subscribe()方法,subscribe()ObservableObserveOn的父類Observable中的方法,所以最終調用到的方法是ObservableObserveOn.subscribeActual(Observer)
  • ObservableSource.subscribeActual(Observer)會收到用戶創建的Observer對象.下面分析subscribeActual(Observer)方法
public final class ObservableObserveOn<T> extends AbstractObservableWithUpstream<T, T> {
    public ObservableObserveOn(ObservableSource<T> source, Scheduler scheduler, boolean delayError, int bufferSize) {
        super(source); // source就是ObservableSubscribeOn對象
        this.scheduler = scheduler;// HandlerScheduler對象
        this.delayError = delayError;
        this.bufferSize = bufferSize;
    }
    // 當前方法中的參數observer就是用戶創建的Observer對象.
    @Override 
    protected void subscribeActual(Observer<? super T> observer) {
        if (scheduler instanceof TrampolineScheduler) {
            source.subscribe(observer);
        } else {
            // 創建HandlerWorker對象
            Scheduler.Worker w = scheduler.createWorker();
            // source.subscribe()調用鏈如下:
            // ObservableSubscribeOn.subscribe()->ObservableSubscribeOn.subscribeActual()->ObserveOnObserver.onSubscribe()->Observe.onSubscribe()
            // 最終觀察者中的onSubscribe()方法將被調用
            source.subscribe(new ObserveOnObserver<T>(observer, w, delayError, bufferSize));
        }
    }
}

到這裏就訂閱成功了.

AndroidSchedulers.mainThread()
  • AndroidSchedulers.mainThread()最終創建了HandlerScheduler對象.
public final class AndroidSchedulers {
    // DEFAULT對象就是一個HandlerScheduler類型的單例
    private static final class MainHolder {
        // Looper.getMainLooper()得到sMainLooper對象,這個sMainLooper對象是在ActivityThread中的main()中創建的,該函數就是運行在UI線程中.
        // 所以到時候用這個Handler發送的消息最終是由主線程中的sMainLooper接收,最終觀察者處理消息的邏輯也將在sMainLooper所屬的線程中執行了.
        static final Scheduler DEFAULT = new HandlerScheduler(new Handler(Looper.getMainLooper()), false);
    }
    // 該方法返回DEFAULT對象
    public static Scheduler mainThread() {
        return RxAndroidPlugins.onMainThreadScheduler(MAIN_THREAD);
    }
    // MAIN_THREAD也是一個單例
    // RxAndroidPlugins.initMainThreadScheduler()下面看下該方法
    private static final Scheduler MAIN_THREAD = RxAndroidPlugins.initMainThreadScheduler(
            new Callable<Scheduler>() {
                @Override public Scheduler call() throws Exception {
                    return MainHolder.DEFAULT;
                }
            });

}
// RxAndroidPlugins類
public final class RxAndroidPlugins {
    public static Scheduler initMainThreadScheduler(Callable<Scheduler> scheduler) {
        ...
        Function<Callable<Scheduler>, Scheduler> f = onInitMainThreadHandler;
        if (f == null) {
            // 該方法最終調用call(),返回MainHolder.DEFAULT對象
            return callRequireNonNull(scheduler);
        }
        return applyRequireNonNull(f, scheduler);
    }
    static Scheduler callRequireNonNull(Callable<Scheduler> s) {
        try {
            Scheduler scheduler = s.call();
            ...
            return scheduler;
        }...
    }
}
觀察者發送數據梳理
  • .subscribe()後發射數據的邏輯.
    • ObservableObserveOn.subscribe(Observer)
    • ObservableObserve.OnsubscribeActual(Observer)
    • ObservableSubscribeOn.subscribe(Observer)
    • ObservableSubscribeOn.OnsubscribeActual(Observer)
    • ObserveOnObserver.onSubscribe(Disposable)⬇ 這裏是調用觀察者onSubscribe()
    • scheduler.scheduleDirect(new SubscribeTask(parent))這一步最終會調用到ObservableOnSubscribe.subscribe(ObservableEmitter)方法,ObservableOnSubscribe.subscribe()寫了發射數據的邏輯.
  • 分析emitter.onNext(100);怎麼將數據發送出去.
    • emitter.onNext(100);中的emitter對象其實是ObservableSubscribeOn.subscribeActual()中創建的SubscribeOnObserver對象.
    • emitter.onNext(100);最終調用SubscribeOnObserver.onNext(T)
    • ObserveOnObserver.onNext(T),ObserveOnObserver對象是在ObservableObserveOn.subscribeActual()方法中創建的.這一步邏輯回到了ObservableObserveOn
  • 邏輯來到了ObserveOnObserver.onNext()這裏
public final class ObservableObserveOn<T> extends AbstractObservableWithUpstream<T, T> {
    static final class ObserveOnObserver<T> extends BasicIntQueueDisposable<T>implements Observer<T>, Runnable {
        ObserveOnObserver(Observer<? super T> actual, Scheduler.Worker worker, boolean delayError, int bufferSize) {
            this.downstream = actual;// 用戶創建的觀察者
            this.worker = worker;// HandlerScheduler對象
            this.delayError = delayError;
            this.bufferSize = bufferSize;
        }
        // t就是要發射的數據對象了
        @Override
        public void onNext(T t) {
            ...
            // 這裏先將消息t存入隊列中,等會發送的時候會將消息取出來的.
            queue.offer(t);
            schedule();
        }
        // this: ObserveOnObserver本身也是一個Runnable對象
        void schedule() {
            if (getAndIncrement() == 0) {
                // worke是HandlerScheduler對象
                worker.schedule(this);
            }
        }
    }
}
  • worker.schedule(this);
final class HandlerScheduler extends Scheduler {
    // 最終調用了這裏的schedule方法.
    // run對象就是ObserveOnObserver對象本身
    public Disposable schedule(Runnable run, long delay, TimeUnit unit) {
        ...
        // ScheduledRunnable類也繼承了Runnable接口,在ScheduledRunnable.run()中會調用ObserveOnObserver對象的run()方法.
        ScheduledRunnable scheduled = new ScheduledRunnable(handler, run);
        Message message = Message.obtain(handler, scheduled);
        ...
        // 將Message發送出去之後,最終會調用ScheduledRunnable對象的run()方法
        // 進而調用ObserveOnObserver對象的run()方法.
        handler.sendMessageDelayed(message, unit.toMillis(delay));
        ...
        return scheduled;
    }
}
  • Handler最終處理消息後就會調用到ObserveOnObserver對象的run()方法.
public final class ObservableObserveOn<T> extends AbstractObservableWithUpstream<T, T> {
    static final class ObserveOnObserver<T> extends BasicIntQueueDisposable<T>implements Observer<T>, Runnable {
        // Handler最終會調用這個地方
        @Override
        public void run() {
            if (outputFused) {
                drainFused();
            } else {
                drainNormal();
            }
        }
        void drainNormal() {
            ...
            // 將消息存儲在隊列中
            final SimpleQueue<T> q = queue;
            // downstream:構造方法中說了,downstream就是用戶創建的觀察者對象.
            final Observer<? super T> a = downstream;
            // 取出消息
            v = q.poll();
            // 最後調用用戶創建的Observer觀察者對象的onNext(v)方法將消息傳出.
            a.onNext(v);
            ..
        }
        void drainFused() {
            ...
            // 觀察者中的onNext()被調用.
            downstream.onNext(null);
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章