RxJava 源碼 解讀

RxJava 源碼解讀
一直以來在網上看到關於RxJava的使用博客都稱讚RxJava使用起來非常簡潔,即使業務邏輯非常複雜,它依然能夠保持簡潔。於是在個人項目也添加了RxJava和RxAndroid.秉着知其然知其所以然的態度,跟着調用方法一探其源碼,

首選是調用方法。這個方法是獲取手機裏面的所有音樂文件信息,並且返回給回調者,並且這裏的subscribe是運行在子線程中,回調則在主線程再更新UI

public void sortMp3InfosByTitleByRx(BaseObserver<List<MusicInfo>> receiver)
    Observable.create(new ObservableOnSubscribe<List<MusicInfo>>() {
            @Override
            public void subscribe(ObservableEmitter<List<MusicInfo>> observableEmitter) throws Exception {
                MusicInfoDao dao=daoSession.getMusicInfoDao();
                DebugLog.d("subscribe:"+Thread.currentThread().getName());
                List<MusicInfo> list=dao.queryBuilder().orderAsc(com.music.bean.MusicInfoDao.Properties.TitleKey).list();
                if (list.isEmpty()){
                    DebugLog.d("本地數據沒有,去手機多媒體數據庫查詢");
                    list.addAll(MusicModel.getInstance().sortMp3InfosByTitle(MusicApplication.getInstance()));
                }else{
                    DebugLog.d("從本地數據庫獲取 ");
                    MusicModel.getInstance().getMusicList().addAll(list);
                }
                musicInfoList.addAll(list);
                observableEmitter.onNext(list);
                observableEmitter.onComplete();
            }

        }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(receiver);

回調者封裝了一個BaseObserver,因爲有時候你只需要其中某一個回調就夠了,

public class BaseObserver<T> implements Observer<T> {
    @Override
    public void onSubscribe(Disposable disposable) {
        DebugLog.d("onSubscribe:"+disposable.toString());
        DebugLog.d(Thread.currentThread().getName());
    }

    @Override
    public void onNext(T t) {
        DebugLog.d("onNext");
        DebugLog.d(Thread.currentThread().getName());
    }

    @Override
    public void onError(Throwable throwable) {
        DebugLog.d("onError");
    }

    @Override
    public void onComplete() {
        DebugLog.d("onComplete");
        DebugLog.d(Thread.currentThread().getName());
    }
}

receiver 是一個BaseObserver子類
其打印如下,正如所想,獲取數據在子線程中,回調給調用者回到了主線程
這裏寫圖片描述
這裏寫圖片描述
那問題來了,這麼幾行代碼如何切換線程?好像我們在獲取數據的時候回調了onNext方法和onComplete方法,怎麼獲取數據的時候是在子線程,而真正給回調者的onNext方法和onComplete方法怎麼又到主線程了?注意到說的是真正onNext方法和onComplete方法,而不是我們在獲取數據的時候調用了onNext和onComplete。

這些都將在我們查看源碼後一一知曉,剛開始第一遍看源碼後,就好像陷入迷霧森林找不到方法一樣,這種感覺是上次看startActivity一樣的感覺,但是後面在反覆從頭查看並且做標記之後,看到後面不解在回過頭看,然後連起來解讀,頓時看透其中原理,簡直有種酣暢淋漓之感,並且感嘆寫出這個代碼人之牛逼哄哄。

下面解讀的是基本的用法的源碼,當然還有高級的用法,後面有時間再查看。

create方法

Observable.java

public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
    ObjectHelper.requireNonNull(source, "source is null");
    return RxJavaPlugins.onAssembly(new ObservableCreate(source));
}

create方法傳入的是我們的創建的ObservableOnSubscribe對象,並且在subscribe方法裏面有我們的業務邏輯,create方法裏面把我們創建的ObservableOnSubscribe對象包裝到ObservableCreate對象
ObservableOnSubscribe是Observable的子類,並且ObservableCreate也是Observable的子類 這個也比較重要,後面我們分析完再來說明。

public final class ObservableCreate<T> extends Observable<T> {
    final ObservableOnSubscribe<T> source;

public ObservableCreate(ObservableOnSubscribe<T> source) {
    this.source = source;
}

可以看到裏面有個source屬性就是創建對象傳入的參數,後面的依然類似,創建對象是傳入的參數大都賦值到對象裏面的souce

RxJavaPlugins onAssembly方法

public static <T> Observable<T> onAssembly(@NonNull Observable<T> source) {
    Function<? super Observable, ? extends Observable> f = onObservableAssembly;
    return f != null?(Observable)apply(f, source):source;
}

onObservableAssembly是調用setOnObservableAssembly方法設置的

public static void setOnObservableAssembly(@Nullable Function<? super Observable, ? extends Observable> onObservableAssembly) {
    if(lockdown) {
        throw new IllegalStateException("Plugins can't be changed anymore");
    } else {
        onObservableAssembly = onObservableAssembly;
    }
}

我們沒有調用這個方法因此這個對象爲Null

public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
    ObjectHelper.requireNonNull(source, "source is null");
    return RxJavaPlugins.onAssembly(new ObservableCreate(source));
}

RxJavaPlugins onAssembly方法 返回的就是ObservableCreate對象
基本上RxJavaPlugins onAssembly方法返回的對象就是傳入的對象
執行完create方法後返回的是ObservableCreate對象,裏面的source就是我們創建的ObservableOnSubscribe對象

subscribeOn方法

2 create之後就是subscribeOn,因爲我想我的業務邏輯運行在子線程中,因此調用了subscribeOn(Schedulers.io())方法。
查看subscribeOn方法,此方法傳入一個Scheduler對象

public final Observable<T> subscribeOn(Scheduler scheduler) {
    ObjectHelper.requireNonNull(scheduler, "scheduler is null");
    return RxJavaPlugins.onAssembly(new ObservableSubscribeOn(this, scheduler));
}

ObservableSubscribeOn構造器把當前對象和我們創建的Schedulers.io()對象也傳入進去,猜想這個應該就是根據我們設置的線程,在我們設置的線程裏面執行我們的方法,ObservableSubscribeOn類繼承了AbstractObservableWithUpstream類,而AbstractObservableWithUpstream類繼承Observable類

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

也就是說ObservableSubscribeOn也是Observable的子類
執行完subscribeOn方法後返回的是ObservableSubscribeOn對象,裏面的source是前面的ObservableCreate對象,scheduler是Schedulers.io()的,

observeOn方法

由於我們想要最終回調到主線程中,因此調用了observeOn(AndroidSchedulers.mainThread())方法

public final Observable<T> observeOn(Scheduler scheduler) {
    return this.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(this, scheduler, delayError, bufferSize));
}

這個和前面那個設置線程的基本都差不多,同樣的ObservableObserveOn也是Observable的子類

public final class ObservableObserveOn<T> extends   AbstractObservableWithUpstream<T, T> {
    final Scheduler scheduler;
    final boolean delayError;
    final int bufferSize;

public ObservableObserveOn(ObservableSource<T> source, Scheduler scheduler, boolean delayError, int bufferSize) {
    super(source);
    this.scheduler = scheduler;
    this.delayError = delayError;
    this.bufferSize = bufferSize;
}

同樣的ObservableObserveOn也是Observable的子類
執行完observeOn方法後返回的是ObservableObserveOn對象,裏面的source是前面的ObservableSubscribeOn對象,scheduler是AndroidSchedulers.mainThread()生成的對象
看最後的subscribe方法

onSubscribe方法

4 到最後執行了subscribe方法,也就是封裝到最後一個對象執行此方法,RxJavaPlugins.onSubscribe(this, observer)返回的就是傳入的observer對象;最後執行了subscribeActual方法

public final void subscribe(Observer<? super T> observer) {
    ObjectHelper.requireNonNull(observer, "observer is null");

    try {
        observer = RxJavaPlugins.onSubscribe(this, observer);
        ObjectHelper.requireNonNull(observer, "Plugin returned null Observer");
        this.subscribeActual(observer);
    } catch (NullPointerException var4) {
        throw var4;
    } catch (Throwable var5) {
        Exceptions.throwIfFatal(var5);
        RxJavaPlugins.onError(var5);
        NullPointerException npe = new NullPointerException("Actually not, but can't throw other exceptions due to RS");
        npe.initCause(var5);
        throw npe;
    }
}

執行subscribeActual方法時發現該方法是個抽象方法

protected abstract void subscribeActual(Observer<? super T> var1);

總結前面的
1. create方法把我們創建的ObservableOnSubscribe對象封裝到ObservableCreate對象
2. subscribeOn方法把ObservableCreate對象封裝到ObservableSubscribeOn對象
3. observeOn方法,把ObservableSubscribeOn對象封裝到ObservableObserveOn對象
4. onSubscribe方法,其實就是調用ObservableObserveOn對象的方法了,該方法傳入了一個Observer,這個Observer就是最後的BaseObserver回調對象
封裝的順序如下

我們創建的ObservableOnSubscribe->ObservableCreate->ObservableSubscribeOn->ObservableObserveOn,並且ObservableCreate,ObservableSubscribeOn,ObservableObserveOn都是Observable的子類

瞭解這個封裝順序很重要,因爲下面的調用前面是一步一步往前回調的。
根據對象的封裝情況,我們再從調用的順序再一步一步往下分析
查看我們的代碼,我也是把這個回調給調用者。先記着這個receiver就是我們自己的回調對象

public void sortMp3InfosByTitleByRx(BaseObserver<List<MusicInfo>> receiver){
    Observable.create(new ObservableOnSubscribe<List<MusicInfo>>() {
        @Override
        public void subscribe(ObservableEmitter<List<MusicInfo>> observableEmitter) throws Exception {
            MusicInfoDao dao=daoSession.getMusicInfoDao();
            DebugLog.d("subscribe:"+Thread.currentThread().getName());
            List<MusicInfo> list=dao.queryBuilder().orderAsc(com.music.bean.MusicInfoDao.Properties.TitleKey).list();
            if (list.isEmpty()){
                DebugLog.d("本地數據沒有,去手機多媒體數據庫查詢");
                list.addAll(MusicModel.getInstance().sortMp3InfosByTitle(MusicApplication.getInstance()));
            }else{
                DebugLog.d("從本地數據庫獲取 ");
                MusicModel.getInstance().getMusicList().addAll(list);
            }
            musicInfoList.addAll(list);
            observableEmitter.onNext(list);
            observableEmitter.onComplete();
        }

    }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(receiver);
}

由前面分析得知,此時執行subscribe方法的是一個ObservableObserveOn對象,因此我們繼續查看
ObservableObserveOn對象裏面的subscribe方法,發現裏面沒有這個方法,查看父類AbstractObservableWithUpstream,裏面也沒有這個方法,繼續父類Observable,裏面有這個方法

總結:Observable子類調用subscribe方法,如果沒有複寫該方法,最終都是自己subscribeActual方法

@SchedulerSupport("none")
public final void subscribe(Observer<? super T> observer) {
    ObjectHelper.requireNonNull(observer, "observer is null");

    try {
        observer = RxJavaPlugins.onSubscribe(this, observer);
        ObjectHelper.requireNonNull(observer, "Plugin returned null Observer");
        this.subscribeActual(observer);
    } catch (NullPointerException var4) {
        throw var4;
    } catch (Throwable var5) {
        Exceptions.throwIfFatal(var5);
        RxJavaPlugins.onError(var5);
        NullPointerException npe = new NullPointerException("Actually not, but can't throw other exceptions due to RS");
        npe.initCause(var5);
        throw npe;
    }
}

查看ObservableObserveOn的subscribeActual方法,這個observer是我們傳入的revicer對象,由前面分析得知,ObservableObserveOn裏面的source是ObservableSubscribeOn對象,這個source對象就是ObservableSubscribeOn對象,因此這裏又回調了ObservableSubscribeOn對象的subscribe方法,並且還創建了一個Worker對象,把我們的revicer對象封裝到一個ObservableObserveOn.ObserveOnObserver對象裏。

ObservableObserveOn的subscribeActual方法

protected void subscribeActual(Observer<? super T> observer) {
    if(this.scheduler instanceof TrampolineScheduler) {
        this.source.subscribe(observer);
    } else {
        Worker w = this.scheduler.createWorker();
        this.source.subscribe(new ObservableObserveOn.ObserveOnObserver(observer, w, this.delayError, this.bufferSize));
    }

}

這裏的scheduler是rxandroid包下面的HandlerScheduler類
HandlerScheduler 筆記
而這裏創建一個worker對象

private static final class HandlerWorker extends Worker {
    public Disposable schedule(Runnable run, long delay, TimeUnit unit) {
        if(run == null) {
            throw new NullPointerException("run == null");
        } else if(unit == null) {
            throw new NullPointerException("unit == null");
        } else if(this.disposed) {
            return Disposables.disposed();
        } else {
            run = RxJavaPlugins.onSchedule(run);
            HandlerScheduler.ScheduledRunnable scheduled = new HandlerScheduler.ScheduledRunnable(this.handler, run);
            Message message = Message.obtain(this.handler, scheduled);
            message.obj = this;
            this.handler.sendMessageDelayed(message, unit.toMillis(delay));
            if(this.disposed) {
                this.handler.removeCallbacks(scheduled);
                return Disposables.disposed();
            } else {
                return scheduled;
            }
        }
    }

    public void dispose() {
        this.disposed = true;
        this.handler.removeCallbacksAndMessages(this);
    }

    public boolean isDisposed() {
        return this.disposed;
    }
}

這個類主要看schedule方法,很顯然是利用handler回調到主線程,這裏暫且先不管這個類,後面調用的時候再回過來看。

繼續看ObservableObserveOn的subscribeActual方法

protected void subscribeActual(Observer<? super T> observer) {
    if(this.scheduler instanceof TrampolineScheduler) {
        this.source.subscribe(observer);
    } else {
        Worker w = this.scheduler.createWorker();
        this.source.subscribe(new ObservableObserveOn.ObserveOnObserver(observer, w, this.delayError, this.bufferSize));
    }

}

既然這個source是ObservableSubscribeOn對象,而這個ObservableSubscribeOn對象也是Observable的子類,由我們前面的分析得知,如果是Observable的子類,調用subsribe方法,就是調用subsribeActual方法,因此我們直接看ObservableSubscribeOn對象的subsribeActual方法,

ObservableSubscribeOn對象的subsribeActual方法

public void subscribeActual(Observer<? super T> s) {
    ObservableSubscribeOn.SubscribeOnObserver<T> parent = new ObservableSubscribeOn.SubscribeOnObserver(s);
    s.onSubscribe(parent);
    parent.setDisposable(this.scheduler.scheduleDirect(new ObservableSubscribeOn.SubscribeTask(parent)));
}

這個SubscribeOnObserver類基本上就是對傳入的s對象做了代理
查看s.onSubscribe方法,這個s就是前面ObservableObserveOn.ObserveOnObserver對象,該對象裏面有我們的receiver對象和一個AndroidSchedulers.mainThread()生成的Worker對象
查看ObservableObserveOn.ObserveOnObserver對象的onSubscribe方法方法,由於傳入進去的parent對象並不是QueueDisposable的子類,因此不會進入if語句裏面,查看this.actual.onSubscribe(this);這個actual就是構造器時傳入的對象,也就是我們的回調對象。

public void onSubscribe(Disposable s) {
        if(DisposableHelper.validate(this.s, s)) {
            this.s = s;
            if(s instanceof QueueDisposable) {
                QueueDisposable<T> qd = (QueueDisposable)s;
                int m = qd.requestFusion(7);
                if(m == 1) {
                    this.sourceMode = m;
                    this.queue = qd;
                    this.done = true;
                    this.actual.onSubscribe(this);
                    this.schedule();
                    return;
                }

                if(m == 2) {
                    this.sourceMode = m;
                    this.queue = qd;
                    this.actual.onSubscribe(this);
                    return;
                }
            }

            this.queue = new SpscLinkedArrayQueue(this.bufferSize);
            this.actual.onSubscribe(this);
        }

    }

到這裏就調用了我們BaseObserver的onSubscribe方法,再看後面是啥時候調用其他方法的

繼續看subscribeActual的方法,執行完s.onSubscribe(parent);後執行
parent.setDisposable(this.scheduler.scheduleDirect(new ObservableSubscribeOn.SubscribeTask(parent)));

ObservableSubscribeOn對象的subsribeActual方法

public void subscribeActual(Observer<? super T> s) {
    ObservableSubscribeOn.SubscribeOnObserver<T> parent = new ObservableSubscribeOn.SubscribeOnObserver(s);
    s.onSubscribe(parent);
    parent.setDisposable(this.scheduler.scheduleDirect(new ObservableSubscribeOn.SubscribeTask(parent)));
}

這裏的s就是是ObservableObserveOn.ObserveOnObserver對象,該對象裏面有我們的receiver對象和一個AndroidSchedulers.mainThread()生成的Worker對象

parent把前面的傳入的參數s進行一個封裝,裏面調用方法基本也就是調用s的方法

這裏又把parent封裝到ObservableSubscribeOn.SubscribeTask對象裏,

ObservableSubscribeOn.SubscribeTask實現了Runnable接口,那主要代碼在run方法裏面,

run方法執行了ObservableSubscribeOn裏面source的subscribe方法。我們知道ObservableSubscribeOn裏面封裝的是ObservableCreate對象,因此這個方法裏面調用的ObservableCreate對象的subscribe方法,這個我們先放着,看後面的代碼是怎麼切換線程的並且調用這個run方法的
SubscribeTask 筆記
final class SubscribeTask implements Runnable {
private final ObservableSubscribeOn.SubscribeOnObserver parent;

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

    public void run() {
        ObservableSubscribeOn.this.source.subscribe(this.parent);
    }
}

繼續查看scheduler對象的scheduleDirect方法

先看schedule怎麼創建的
這個scheduler是創建ObservableSubscribeOn對象時創建的,找到前面創建ObservableSubscribeOn對象的代碼

public final Observable<T> observeOn(Scheduler scheduler) {
    return this.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(this, scheduler, delayError, bufferSize));
}

創建new ObservableObserveOn(this, scheduler, delayError, bufferSize),時這個scheuler就是我們調用Schedulers.io()傳入進去的。

scheduler的scheduleDirect方法

@NonNull
public Disposable scheduleDirect(@NonNull Runnable run, long delay, @NonNull TimeUnit unit) {
    Scheduler.Worker w = this.createWorker();
    Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
    Scheduler.DisposeTask task = new Scheduler.DisposeTask(decoratedRun, w);
    w.schedule(task, delay, unit);
    return task;
}

Scheduler主要是調用其createWorker生成的Worker對象的schedule的方法.而我們用的是Schedulers.io()生成的是NewThreadScheduler類
NewThreadScheduler類的創建的是一個NewThreadWorker。

@NonNull
public Worker createWorker() {
    return new NewThreadWorker(this.threadFactory);
}

NewThreadWorker類的schedule方法,調用了重載方法,重載方法調用了scheduleActual方法

@NonNull
public Disposable schedule(@NonNull Runnable run) {
    return this.schedule(run, 0L, (TimeUnit)null);
}

@NonNull
public Disposable schedule(@NonNull Runnable action, long delayTime, @NonNull TimeUnit unit) {
    return (Disposable)(this.disposed?EmptyDisposable.INSTANCE:this.scheduleActual(action, delayTime, unit, (DisposableContainer)null));
}
@NonNull
public ScheduledRunnable scheduleActual(Runnable run, long delayTime, @NonNull TimeUnit unit, @Nullable DisposableContainer parent) {
    Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
    ScheduledRunnable sr = new ScheduledRunnable(decoratedRun, parent);
    if(parent != null && !parent.add(sr)) {
        return sr;
    } else {
        try {
            Object f;
            if(delayTime <= 0L) {
                f = this.executor.submit(sr);
            } else {
                f = this.executor.schedule(sr, delayTime, unit);
            }

            sr.setFuture((Future)f);
        } catch (RejectedExecutionException var10) {
            if(parent != null) {
                parent.remove(sr);
            }

            RxJavaPlugins.onError(var10);
        }

        return sr;
    }
}

再看前面 調用的代碼

ObservableSubscribeOn對象的subsribeActual方法,

public void subscribeActual(Observer<? super T> s) {
    ObservableSubscribeOn.SubscribeOnObserver<T> parent = new ObservableSubscribeOn.SubscribeOnObserver(s);
    s.onSubscribe(parent);
    parent.setDisposable(this.scheduler.scheduleDirect(new ObservableSubscribeOn.SubscribeTask(parent)));
}

ObservableSubscribeOn.SubscribeTask是一個實現了Runnable的子類,而調用這個scheduler的裏面的Worker對象就是NewThreadWorker,這個對象裏面有個線程池,運行在這裏的代碼都是在子線程中進行的,ObservableSubscribeOn.SubscribeTask根據時間是否直接提交到線程池中,還是延遲提交。

前面在SubscribeTask 筆記記錄,現在這裏的參數run就是前面的SubscribeTask對象,這裏又封裝成一個ScheduledRunnable對象,不過這個ScheduledRunnable對象調用的也是傳入run的方法。
再查看SubscribeTask類,調用的是ObservableSubscribeOn裏面source對象的方法, 也就是ObservableCreate的方法

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

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

    public void run() {
        ObservableSubscribeOn.this.source.subscribe(this.parent);
    }
}

根據前面總結得知,調用subscribe方法就是調用ObservableCreate的subscribeActual方法

ObservableCreate的subscribeActual方法

protected void subscribeActual(Observer<? super T> observer) {
    ObservableCreate.CreateEmitter<T> parent = new ObservableCreate.CreateEmitter(observer);
    observer.onSubscribe(parent);

    try {
        this.source.subscribe(parent);
    } catch (Throwable var4) {
        Exceptions.throwIfFatal(var4);
        parent.onError(var4);
    }

}

這裏繼續調用的source,也就是我們自己創建的一個ObservableOnSubscribe

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章