Android主流三方庫原始碼分析(五、深入理解RxJava原始碼)

jsonchao發表於2020-02-19

前言

成為一名優秀的Android開發,需要一份完備的知識體系,在這裡,讓我們一起成長為自己所想的那樣~。

到目前為止筆者分析了Android中最熱門的網路底層和封裝框架:Android主流三方庫原始碼分析(一、深入理解OKHttp原始碼)Android主流三方庫原始碼分析(二、深入理解Retrofit原始碼),Android中使用最廣泛的圖片載入框架Glide的載入流程:Android主流三方庫原始碼分析(三、深入理解Glide原始碼)以及Android中效能最好的資料庫框架Android主流三方庫原始碼分析(四、深入理解GreenDao原始碼)。本篇,我將會對近幾年比較熱門的函數語言程式設計框架RxJava的原始碼進行詳細的分析。

一、RxJava到底是什麼?

RxJava是基於Java虛擬機器上的響應式擴充套件庫,它通過使用可觀察的序列將非同步和基於事件的程式組合起來。 與此同時,它擴充套件了觀察者模式來支援資料/事件序列,並且新增了操作符,這些操作符允許你宣告性地組合序列,同時抽象出要關注的問題:比如低階執行緒、同步、執行緒安全和併發資料結構等。

從RxJava的官方定義來看,我們如果要想真正地理解RxJava,就必須對它以下兩個部分進行深入的分析:

  • 1、訂閱流程
  • 2、執行緒切換

當然,RxJava操作符的原始碼也是很不錯的學習資源,特別是FlatMap、Zip等操作符的原始碼,有很多可以借鑑的地方,但是它們內部的實現比較複雜,限於篇幅,本文只講解RxJava的訂閱流程和執行緒切換原理。接下來,筆者一一對以上RxJava的兩個關鍵部分來進行詳細地講解。

二、RxJava的訂閱流程

首先給出RxJava訊息訂閱的例子:

Observable.create(newObservableOnSubscribe<String>() {
    @Override
    public void subscribe(ObservableEmitter<String>emitter) throws Exception {
        emitter.onNext("1");
        emitter.onNext("2");
        emitter.onNext("3");
        emitter.onComplete();
    }
}).subscribe(new Observer<String>() {
    @Override
    public void onSubscribe(Disposable d) {
        Log.d(TAG, "onSubscribe");
    }
    @Override
    public void onNext(String s) {
        Log.d(TAG, "onNext : " + s);
    }
    @Override
    public void onError(Throwable e) {
        Log.d(TAG, "onError : " + e.toString());
    }
    @Override
    public void onComplete() {
        Log.d(TAG, "onComplete");
    }
});
複製程式碼

可以看到,這裡首先建立了一個被觀察者,然後建立一個觀察者訂閱了這個被觀察者,因此下面分兩個部分對RxJava的訂閱流程進行分析:

  • 1、建立被觀察者過程
  • 2、訂閱過程

1、建立被觀察者過程

首先,上面使用了Observable類的create()方法建立了一個被觀察者,看看裡面做了什麼。

1.1、Observable#create()
// 省略一些檢測性的註解
public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
    ObjectHelper.requireNonNull(source, "source is null");
    return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
}
複製程式碼

在Observable的create()裡面實際上是建立了一個新的ObservableCreate物件,同時,把我們定義好的ObservableOnSubscribe物件傳入了ObservableCreate物件中,最後呼叫了RxJavaPlugins.onAssembly()方法。接下來看看這個ObservableCreate是幹什麼的。

1.2、ObservableCreate
public final class ObservableCreate<T> extends Observable<T> {

    final ObservableOnSubscribe<T> source;

    public ObservableCreate(ObservableOnSubscribe<T> source) {
        this.source = source;
    }
    
    ...
}
複製程式碼

這裡僅僅是把ObservableOnSubscribe這個物件儲存在ObservableCreate中了。然後看看RxJavaPlugins.onAssembly()這個方法的處理。

1.3、RxJavaPlugins#onAssembly()
public static <T> Observable<T> onAssembly(@NonNull Observable<T> source) {

    // 應用hook函式的一些處理,一般用到不到
    ...
    return source;
}
複製程式碼

最終僅僅是把我們的ObservableCreate給返回了。

1.4、建立被觀察者過程小結

從以上分析可知,Observable.create()方法僅僅是先將我們自定義的ObservableOnSubscribe物件重新包裝成了一個ObservableCreate物件

2、訂閱過程

接著,看看Observable.subscribe()的訂閱過程是如何實現的。

2.1、Observable#subscribe()
public final void subscribe(Observer<? super T> observer) {
    ...
    
    // 1
    observer = RxJavaPlugins.onSubscribe(this,observer);
    
    ...
    
    // 2
    subscribeActual(observer);
    
    ...
}
複製程式碼

在註釋1處,在Observable的subscribe()方法內部首先呼叫了RxJavaPlugins的onSubscribe()方法。

2.2、RxJavaPlugins#onSubscribe()
public static <T> Observer<? super T> onSubscribe(@NonNull Observable<T> source, @NonNull Observer<? super T> observer) {

    // 應用hook函式的一些處理,一般用到不到
    ...
    
    return observer;
}
複製程式碼

除去hook應用的邏輯,這裡僅僅是將observer返回了。接著來分析下注釋2處的subscribeActual()方法,

2.3、Observable#subscribeActual()
protected abstract void subscribeActual(Observer<? super T> observer);
複製程式碼

這是一個抽象的方法,很明顯,它對應的具體實現類就是我們在第一步建立的ObservableCreate類,接下來看到ObservableCreate的subscribeActual()方法。

2.4、ObservableCreate#subscribeActual()
@Override
protected void subscribeActual(Observer<? super T> observer) {
    // 1
    CreateEmitter<T> parent = new CreateEmitter<T>(observer);
    // 2
    observer.onSubscribe(parent);

    try {
        // 3
        source.subscribe(parent);
    } catch (Throwable ex) {
        Exceptions.throwIfFatal(ex);
        parent.onError(ex);
    }
}
複製程式碼

在註釋1處,首先新建立了一個CreateEmitter物件,同時傳入了我們自定義的observer物件進去。

2.4.1、CreateEmitter
static final class CreateEmitter<T>
extends AtomicReference<Disposable>
implements ObservableEmitter<T>, Disposable {

    ...
    
    final Observer<? super T> observer;

    CreateEmitter(Observer<? super T> observer) {
        this.observer = observer;
    }
    
    ...
}
複製程式碼

從上面可以看出,CreateEmitter通過繼承了Java併發包中的原子引用類AtomicReference保證了事件流切斷狀態Dispose的一致性(這裡不理解的話,看到後面講解Dispose的時候就明白了),並實現了ObservableEmitter介面和Disposable介面,接著我們分析下注釋2處的observer.onSubscribe(parent),這個onSubscribe回撥的含義其實就是告訴觀察者已經成功訂閱了被觀察者。再看到註釋3處的source.subscribe(parent)這行程式碼,這裡的source其實是ObservableOnSubscribe物件,我們看到ObservableOnSubscribe的subscribe()方法。

2.4.2、ObservableOnSubscribe#subscribe()
Observable observable = Observable.create(new ObservableOnSubscribe<String>() {
    @Override
    public voidsubscribe(ObservableEmitter<String> emitter) throws Exception {
        emitter.onNext("1");
        emitter.onNext("2");
        emitter.onNext("3");
        emitter.onComplete();
    }
});
複製程式碼

這裡面使用到了ObservableEmitter的onNext()方法將事件流傳送出去,最後呼叫了onComplete()方法完成了訂閱過程。ObservableEmitter是一個抽象類,實現類就是我們傳入的CreateEmitter物件,接下來我們看看CreateEmitter的onNext()方法和onComplete()方法的處理。

2.4.3、CreateEmitter#onNext() && CreateEmitter#onComplete()
static final class CreateEmitter<T>
extends AtomicReference<Disposable>
implements ObservableEmitter<T>, Disposable {

...

@Override
public void onNext(T t) {
    ...
    
    if (!isDisposed()) {
        //呼叫觀察者的onNext()
        observer.onNext(t);
    }
}

@Override
public void onComplete() {
    if (!isDisposed()) {
        try {
            observer.onComplete();
        } finally {
            dispose();
        }
    }
}


...

}
複製程式碼

在CreateEmitter的onNext和onComplete方法中首先都要經過一個isDisposed的判斷,作用就是看當前的事件流是否被切斷(廢棄)掉了,預設是不切斷的,如果想要切斷,可以呼叫Disposable的dispose()方法將此狀態設定為切斷(廢棄)狀態。我們繼續看看這個isDisposed內部的處理。

2.4.4、ObservableEmitter#isDisposed()
@Override
public boolean isDisposed() {
    return DisposableHelper.isDisposed(get());
}
複製程式碼

注意到這裡通過get()方法首先從ObservableEmitter的AtomicReference中拿到了儲存的Disposable狀態。然後交給了DisposableHelper進行判斷處理。接下來看看DisposableHelper的處理。

2.4.5、DisposableHelper#isDisposed() && DisposableHelper#set()
public enum DisposableHelper implements Disposable {

    DISPOSED;

    public static boolean isDisposed(Disposable d) {
        // 1
        return d == DISPOSED;
    }
    
    public static boolean set(AtomicReference<Disposable> field, Disposable d) {
        for (;;) {
            Disposable current = field.get();
            if (current == DISPOSED) {
                if (d != null) {
                    d.dispose();
                }
                return false;
            }
            // 2
            if (field.compareAndSet(current, d)) {
                if (current != null) {
                    current.dispose();
                }
                return true;
            }
        }
    }
    
    ...
    
    public static boolean dispose(AtomicReference<Disposable> field) {
        Disposable current = field.get();
        Disposable d = DISPOSED;
        if (current != d) {
            // ...
            current = field.getAndSet(d);
            if (current != d) {
                if (current != null) {
                    current.dispose();
                }
                return true;
            }
        }
        return false;
    }
    
    ...
}
複製程式碼

DisposableHelper是一個列舉類,內部只有一個值即DISPOSED, 從上面的分析可知它就是用來標記事件流被切斷(廢棄)狀態的。先看到註釋2和註釋3處的程式碼field.compareAndSet(current, d)和field.getAndSet(d),這裡使用了原子引用AtomicReference內部包裝的CAS方法處理了標誌Disposable的併發讀寫問題。最後看到註釋3處,將我們傳入的CreateEmitter這個原子引用類儲存的Dispable狀態和DisposableHelper內部的DISPOSED進行比較,如果相等,就證明資料流被切斷了。為了更進一步理解Disposed的作用,再來看看CreateEmitter中剩餘的關鍵方法。

2.4.6、CreateEmitter
@Override
public void onNext(T t) {
    ...
    // 1
    if (!isDisposed()) {
        observer.onNext(t);
    }
}

@Override
public void onError(Throwable t) {
    if (!tryOnError(t)) {
        // 2
        RxJavaPlugins.onError(t);
    }
}

@Override
public boolean tryOnError(Throwable t) {
    ...
    // 3
    if (!isDisposed()) {
        try {
            observer.onError(t);
        } finally {
            // 4
            dispose();
        }
        return true;
    }
    return false;
}

@Override
public void onComplete() {
    // 5
    if (!isDisposed()) {
        try {
            observer.onComplete();
        } finally {
            // 6
            dispose();
        }
    }
}
複製程式碼

在註釋1、3、5處,onNext()和onError()、onComplete()方法首先都會判斷事件流是否被切斷,如果事件流此時被切斷了,那麼onNext()和onComplete()則會退出方法體,不做處理,onError()則會執行到RxJavaPlugins.onError(t)這句程式碼,內部會直接丟擲異常,導致崩潰。如果事件流沒有被切斷,那麼在onError()和onComplete()內部最終會呼叫到註釋4、6處的這句dispose()程式碼,將事件流進行切斷,由此可知,onError()和onComplete()只能呼叫一個,如果先執行的是onComplete(),再呼叫onError()的話就會導致異常崩潰

三、RxJava的執行緒切換

首先給出RxJava執行緒切換的例子:

Observable.create(new ObservableOnSubscribe<String>() {
    @Override
    public voidsubscribe(ObservableEmitter<String>emitter) throws Exception {
        emitter.onNext("1");
        emitter.onNext("2");
        emitter.onNext("3");
        emitter.onComplete();
    }
}) 
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(new Observer<String>() {
        @Override
        public void onSubscribe(Disposable d) {
            Log.d(TAG, "onSubscribe");
        }
        @Override
        public void onNext(String s) {
            Log.d(TAG, "onNext : " + s);
        }
        @Override
        public void onError(Throwable e) {
            Log.d(TAG, "onError : " +e.toString());
        }
        @Override
        public void onComplete() {
            Log.d(TAG, "onComplete");
        }
});
複製程式碼

可以看到,RxJava的執行緒切換主要分為subscribeOn()和observeOn()方法,首先,來分析下subscribeOn()方法。

1、subscribeOn(Schedulers.io())

在Schedulers.io()方法中,我們需要先傳入一個Scheduler排程類,這裡是傳入了一個排程到io子執行緒的排程類,我們看看這個Schedulers.io()方法內部是怎麼構造這個排程器的。

2、Schedulers#io()

static final Scheduler IO;

...

public static Scheduler io() {
    // 1
    return RxJavaPlugins.onIoScheduler(IO);
}

static {
    ...

    // 2
    IO = RxJavaPlugins.initIoScheduler(new IOTask());
}

static final class IOTask implements Callable<Scheduler> {
    @Override
    public Scheduler call() throws Exception {
        // 3
        return IoHolder.DEFAULT;
    }
}

static final class IoHolder {
    // 4
    static final Scheduler DEFAULT = new IoScheduler();
}
複製程式碼

Schedulers這個類的程式碼很多,這裡我只拿出有關Schedulers.io這個方法涉及的邏輯程式碼進行講解。首先,在註釋1處,同前面分析的訂閱流程的處理一樣,只是一個處理hook的邏輯,最終返回的還是傳入的這個IO物件。再看到註釋2處,在Schedulers的靜態程式碼塊中將IO物件進行了初始化,其實質就是新建了一個IOTask的靜態內部類,在IOTask的call方法中,也就是註釋3處,可以瞭解到使用了靜態內部類的方式把建立的IOScheduler物件給返回出去了。繞了這麼大圈子,Schedulers.io方法其實質就是返回了一個IOScheduler物件

3、Observable#subscribeOn()

  public final Observable<T> subscribeOn(Scheduler scheduler) {
    ...
    
    return RxJavaPlugins.onAssembly(new ObservableSubscribeOn<T>(this, scheduler));
}
複製程式碼

在subscribeOn()方法裡面,又將ObservableCreate包裝成了一個ObservableSubscribeOn物件。我們關注到ObservableSubscribeOn類。

4、ObservableSubscribeOn

public final class ObservableSubscribeOn<T> extends AbstractObservableWithUpstream<T, T> {
    final Scheduler scheduler;

    public ObservableSubscribeOn(ObservableSource<T> source, Scheduler scheduler) {
        // 1
        super(source);
        this.scheduler = scheduler;
    }

    @Override
    public void subscribeActual(final Observer<? super T> observer) {
        // 2
        final SubscribeOnObserver<T> parent = new SubscribeOnObserver<T>(observer);
        
        // 3
        observer.onSubscribe(parent);
        
        // 4
        parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)));
    }

...
}
複製程式碼

首先,在註釋1處,將傳進來的source和scheduler儲存起來。接著,等到實際訂閱的時候,就會執行到這個subscribeActual方法,在註釋2處,將我們自定義的Observer包裝成了一個SubscribeOnObserver物件。在註釋3處,通知觀察者訂閱了被觀察者。在註釋4處,內部先建立了一個SubscribeTask物件,來看看它的實現。

5、ObservableSubscribeOn#SubscribeTask

final class SubscribeTask implements Runnable {
    private final SubscribeOnObserver<T> parent;

    SubscribeTask(SubscribeOnObserver<T> parent) {
        this.parent = parent;
    }

    @Override
    public void run() {
        source.subscribe(parent);
    }
}
複製程式碼

SubscribeTask是ObservableSubscribeOn的內部類,它實質上就是一個任務類,在它的run方法中會執行到source.subscribe(parent)的訂閱方法,這個source其實就是我們在ObservableSubscribeOn構造方法中傳進來的ObservableCreate物件。接下來看看scheduler.scheduleDirect()內部的處理。

6、Scheduler#scheduleDirect()

public Disposable scheduleDirect(@NonNull Runnable run) {
    return scheduleDirect(run, 0L, TimeUnit.NANOSECONDS);
}

public Disposable scheduleDirect(@NonNull Runnable run, long delay, @NonNull TimeUnit unit) {

    // 1
    final Worker w = createWorker();

    // 2
    final Runnable decoratedRun = RxJavaPlugins.onSchedule(run);

    // 3
    DisposeTask task = new DisposeTask(decoratedRun, w);

    // 4
    w.schedule(task, delay, unit);

    return task;
}
複製程式碼

這裡最後會執行到上面這個scheduleDirect()過載方法。首先,在註釋1處,會呼叫createWorker()方法建立一個工作者物件Worker,它是一個抽象類,這裡的實現類就是IoScheduler,下面,我們看看IoScheduler類的createWorker()方法。

6.1、IOScheduler#createWorker()
final AtomicReference<CachedWorkerPool> pool;

...

public IoScheduler(ThreadFactory threadFactory) {
    this.threadFactory = threadFactory;
    this.pool = new AtomicReference<CachedWorkerPool>(NONE);
    start();
}

...

@Override
public Worker createWorker() {
    // 1
    return new EventLoopWorker(pool.get());
}

static final class EventLoopWorker extends Scheduler.Worker {
    ...

    EventLoopWorker(CachedWorkerPool pool) {
        this.pool = pool;
        this.tasks = new CompositeDisposable();
        // 2
        this.threadWorker = pool.get();
    }
    
}
複製程式碼

首先,在註釋1處呼叫了pool.get()這個方法,pool是一個CachedWorkerPool型別的原子引用物件,它的作用就是用於快取工作者物件Worker的。然後,將得到的CachedWorkerPool傳入新建立的EventLoopWorker物件中。重點關注一下注釋2處,這裡將CachedWorkerPool快取的threadWorker物件儲存起來了。

下面,我們繼續分析3.6處程式碼段的註釋2處的程式碼,這裡又是一個關於hook的封裝處理,最終還是返回的當前的Runnable物件。在註釋3處新建了一個切斷任務DisposeTask將decoratedRun和w物件包裝了起來。最後在註釋4處呼叫了工作者的schedule()方法。下面我們來分析下它內部的處理。

6.2、IoScheduler#schedule()
@Override
public Disposable schedule(@NonNull Runnableaction, long delayTime, @NonNull TimeUnit unit){
    ...
    
    return threadWorker.scheduleActual(action,delayTime, unit, tasks);
}
複製程式碼

內部呼叫了threadWorker的scheduleActual()方法,實際上是呼叫到了父類NewThreadWorker的scheduleActual()方法,我們繼續看看NewThreadWorker的scheduleActual()方法中做的事情。

6.3、NewThreadWorker#scheduleActual()
public NewThreadWorker(ThreadFactory threadFactory) {
    executor = SchedulerPoolFactory.create(threadFactory);
}


@NonNull
public ScheduledRunnable scheduleActual(final Runnable run, long delayTime, @NonNull TimeUnit unit, @Nullable DisposableContainer parent) {
    Runnable decoratedRun = RxJavaPlugins.onSchedule(run);

    // 1
    ScheduledRunnable sr = new ScheduledRunnable(decoratedRun, parent);
    
   
    if (parent != null) {
        if (!parent.add(sr)) {
            return sr;
        }
    }

    Future<?> f;
    try {
        // 2
        if (delayTime <= 0) {
            // 3
            f = executor.submit((Callable<Object>)sr);
        } else {
            // 4
            f = executor.schedule((Callable<Object>)sr, delayTime, unit);
        }
        sr.setFuture(f);
    } catch (RejectedExecutionException ex) {
        if (parent != null) {
            parent.remove(sr);
        }
        RxJavaPlugins.onError(ex);
    }

    return sr;
}
複製程式碼

在NewThreadWorker的scheduleActual()方法的內部,在註釋1處首先會新建一個ScheduledRunnable物件,將Runnable物件和parent包裝起來了,這裡parent是一個DisposableContainer物件,它實際的實現類是CompositeDisposable類,它是一個儲存所有事件流是否被切斷狀態的容器,其內部的實現是使用了RxJava自己定義的一個簡單的OpenHashSet類進行儲存。最後註釋2處,判斷是否設定了延遲時間,如果設定了,則呼叫執行緒池的submit()方法立即進行執行緒切換,否則,呼叫schedule()方法進行延時執行執行緒切換。

7、為什麼多次執行subscribeOn(),只有第一次有效?

從上面的分析,我們可以很容易瞭解到被觀察者被訂閱時是從最外面的一層(ObservableSubscribeOn)通知到裡面的一層(ObservableOnSubscribe),當連續執行了到多次subscribeOn()的時候,其實就是先執行倒數第一次的subscribeOn()方法,直到最後一次執行的subscribeOn()方法,這樣肯定會覆蓋前面的執行緒切換。

8、observeOn(AndroidSchedulers.mainThread())

public final Observable<T> observeOn(Scheduler scheduler) {
    return observeOn(scheduler, false, bufferSize());
}

public final Observable<T> observeOn(Scheduler scheduler, boolean delayError, int bufferSize) {
    ....
    
    return RxJavaPlugins.onAssembly(new ObservableObserveOn<T>(this, scheduler, delayError, bufferSize));
}
複製程式碼

可以看到,observeOn()方法內部最終也是返回了一個ObservableObserveOn物件,我們直接來看看ObservableObserveOn的subscribeActual()方法。

9、ObservableObserveOn#subscribeActual()

@Override
protected void subscribeActual(Observer<? super T> observer) {
    // 1
    if (scheduler instanceof TrampolineScheduler) {
        // 2
        source.subscribe(observer);
    } else {
        // 3
        Scheduler.Worker w = scheduler.createWorker();
        // 4
        source.subscribe(new ObserveOnObserver<T>(observer, w, delayError, bufferSize));
    }
}
複製程式碼

首先,在註釋1處,判斷指定的排程器是不是TrampolineScheduler,這是一個不進行執行緒切換,立即執行當前程式碼的排程器。如果是,則會直接呼叫ObservableSubscribeOn的subscribe()方法,如果不是,則會在註釋3處建立一個工作者物件。然後,在註釋4處建立一個新的ObserveOnObserver將SubscribeOnobserver物件包裝起來,並傳入ObservableSubscribeOn的subscribe()方法進行訂閱。接下來看看ObserveOnObserver類的重點方法。

10、ObserveOnObserver

@Override
public void onNext(T t) {
    ...
    if (sourceMode != QueueDisposable.ASYNC) {
        // 1
        queue.offer(t);
    }
    schedule();
}

@Override
public void onError(Throwable t) {
    ...
    schedule();
}

@Override
public void onComplete() {
    ...
    schedule();
}
複製程式碼

去除非主線邏輯的程式碼,在ObserveOnObserver的onNext()和onError()、onComplete()方法中最後都會呼叫到schedule()方法。接著看schedule()方法,其中onNext()還會把訊息存放到佇列中

11、ObserveOnObserver#schedule()

void schedule() {
    if (getAndIncrement() == 0) {
        worker.schedule(this);
    }
}
複製程式碼

這裡使用了worker進行排程ObserveOnObserver這個實現了Runnable的任務。worker就是在AndroidSchedulers.mainThread()中建立的,內部其實就是使用Handler進行執行緒切換的,此處不再贅述了。接著看ObserveOnObserver的run()方法。

12、ObserveOnObserver#run()

@Override
public void run() {
    // 1
    if (outputFused) {
        drainFused();
    } else {
        // 2
        drainNormal();
    }
}
複製程式碼

在註釋1處會先判斷outputFused這個標誌位,它表示事件流是否被融化掉,預設是false,所以,最後會執行到drainNormal()方法。接著看看drainNormal()方法內部的處理。

13、ObserveOnObserver#drainNormal()

void drainNormal() {
    int missed = 1;
    
    final SimpleQueue<T> q = queue;
    
    // 1
    final Observer<? super T> a = downstream;
    
    ...
    
    // 2
    v = q.poll();
    
    ...
    // 3
    a.onNext(v);
    
    ...
}
複製程式碼

在註釋1處,這裡的downstream實際上是從外面傳進來的SubscribeOnObserver物件。在註釋2處將佇列中的訊息取出來,接著在註釋3處呼叫了SubscribeOnObserver的onNext方法。最終,會從我們包裝類的最外層一直呼叫到最裡面的我們自定義的Observer中的onNext()方法,所以,在observeOn()方法下面的鏈式程式碼都會執行到它所指定的執行緒中,噢,原來如此

五、總結

其實筆者使用了RxJava也已經有一年多的時間了,但是一直沒有去深入去了解過它的內部實現原理,如今細細品嚐,的確是酣暢淋漓。從一開始的OkHttp到現如今的RxJava原始碼分析,到此為止,Android主流三方庫原始碼分析系列文章已經發布了五篇了,我們的征途已經過半,接下來,我將會對Android中的記憶體洩露框架LeakCanary原始碼進行深入地講解,盡請期待~

參考連結:

1、RxJava V2.2.5 原始碼

2、Android 進階之光

3、詳解 RxJava 的訊息訂閱和執行緒切換原理


Contanct Me

● 微信:

歡迎關注我的微信:bcce5360

● 微信群:

微信群如果不能掃碼加入,麻煩大家想進微信群的朋友們,加我微信拉你進群。

Android主流三方庫原始碼分析(五、深入理解RxJava原始碼)

● QQ群:

2千人QQ群,Awesome-Android學習交流群,QQ群號:959936182, 歡迎大家加入~

About me

很感謝您閱讀這篇文章,希望您能將它分享給您的朋友或技術群,這對我意義重大。

希望我們能成為朋友,在 Github掘金上一起分享知識。

相關文章