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