在上一篇文章中,我基於Obervable類介紹了RxJava的基本用法,再貼一遍代碼
Observable.just("hello") // 代碼1:創建observable
.subscribeOn(Schedulers.io()) // 代碼2:用subscribeOn操作符變換observable
.observeOn(Schedulers.newThread()) // 代碼3:用observeOn操作符變換observable
.subscribe(new Consumer<String>() { // 代碼4:訂閱observer
@Override
public void accept(String s) throws Exception {
System.out.println(s);
}
});
還是原來的三段式,創建observable,變換observable,訂閱observer。
上面的4句代碼,我們逐一分析,先看代碼1
public static <T> Observable<T> just(T item) {
ObjectHelper.requireNonNull(item, "The item is null");
return RxJavaPlugins.onAssembly(new ObservableJust<T>(item));
}
可以看到代碼1會返回一個ObservableJust對象,點進去可以發現它是一個Observable對象,保存有item值。
其中RxJavaPlugins.onAssembly只是一個hook assembly的行爲,可以忽略。
代碼2
public final Observable<T> subscribeOn(Scheduler scheduler) {
ObjectHelper.requireNonNull(scheduler, "scheduler is null");
return RxJavaPlugins.onAssembly(new ObservableSubscribeOn<T>(this, scheduler));
}
它返回一個ObservableSubscribeOn對象,同樣也是一個Observable對象,然後它有一個source變量保存調用方,即代碼1返回的obverable。
代碼3
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));
}
它返回一個ObservableOberveOn對象,同樣也是一個Observable對象,然後它有一個source變量保存調用方,即代碼2返回的obverable。
代碼4
public final Disposable subscribe(Consumer<? super T> onNext) {
return subscribe(onNext, Functions.ON_ERROR_MISSING, Functions.EMPTY_ACTION, Functions.emptyConsumer());
}
public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError,
Action onComplete, Consumer<? super Disposable> onSubscribe) {
// 忽略兼容性代碼
LambdaObserver<T> ls = new LambdaObserver<T>(onNext, onError, onComplete, onSubscribe);
subscribe(ls);
return ls;
}
// 最終調用到的方法
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");
subscribeActual(observer);
} catch (NullPointerException e) { // NOPMD
throw e;
} catch (Throwable e) {
// 忽略部分代碼
throw npe;
}
}
如前面文章所講,訂閱observer最後都會跑到這個subscribe(observer)方法,在一系列訂閱方法中,必要的時候會先構造一個Observer對象,如上述代碼中的LambdaObserver。我們重點看最終調用的這個方法。
可以看到subscribe方法其實就是調用subscribleActual(observer)方法,這是個virtual method,每個Observable的子類都會實現。
這裏我們看一下代碼3返回的ObservableOberveOn類的實現
@Override
protected void subscribeActual(Observer<? super T> observer) {
// scheduler爲當前線程
if (scheduler instanceof TrampolineScheduler) {
source.subscribe(observer);
} else {
// scheduler爲其它線程
// 指定scheduler創建worker
Scheduler.Worker w = scheduler.createWorker();
source.subscribe(new ObserveOnObserver<T>(observer, w, delayError, bufferSize));
}
}
重點是這裏會包裝observer爲OberveOnOberver對象,然後訂閱上游的observable。看上游observable即代碼2返回的ObservableSubscribeOn對象的訂閱實現,同樣是subscribeActual方法
@Override
public void subscribeActual(final Observer<? super T> s) {
final SubscribeOnObserver<T> parent = new SubscribeOnObserver<T>(s);
// 調用下游observer的onSubscrible
s.onSubscribe(parent);
// SubscribeTask爲訂閱上游observable
parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)));
}
final class SubscribeTask implements Runnable {
private final SubscribeOnObserver<T> parent;
SubscribeTask(SubscribeOnObserver<T> parent) {
this.parent = parent;
}
@Override
public void run() {
source.subscribe(parent);
}
}
可以看到,同樣是先包裝來自下游的observer爲SubscribeOnObserver,然後訂閱上游的observable,另外這裏會指定“訂閱上游的observable”在哪個線程執行。
繼續跟蹤看上游observable即代碼1返回的ObservableJust對象的subscribleActual方法
@Override
protected void subscribeActual(Observer<? super T> s) {
ScalarDisposable<T> sd = new ScalarDisposable<T>(s, value);
s.onSubscribe(sd);
sd.run();
}
其中ScalarDisposable的run方法如下
@Override
public void run() {
if (get() == START && compareAndSet(START, ON_NEXT)) {
observer.onNext(value);
if (get() == ON_NEXT) {
lazySet(ON_COMPLETE);
observer.onComplete();
}
}
}
可以看到最上游的observable會先調用observer的onSubscrible方法,然後發射數據,視情況調用observer的onNext, onComplete或者onError方法。
在這之後,各個observer包裝有下游的observer,一般命名爲actual,在收到事件後,同樣會視情況調用actual的各個回調方法。
總結一下數據的流向:
observable創建後可以先不理會它是否發射數據,各種操作符變換僅僅是包裝上游的observable,待執行subscrible時會自下游往上游回溯,層層包裝observer並訂閱上游observable,最終到達最上游的observable,在最上游observable的subscrible方法(實際爲subscribleActual)開始發射數據給observer處理,各observer處理數據後會視情況調用下游observer的各個回調方法。
到這裏RxJava的原理已經講完,各種操作符的作用無非是分析兩點
1. subscrible下游向上游回溯的時候subscribleActual除了包裝observer還做了什麼
2. 最頂層observable發射數據後自上游向下遊observer各自做了什麼