在上一篇文章中,我基于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的原理已经讲完,各种操作符的作用无非是分析两点
- subscrible下游向上游回溯的时候subscribleActual除了包装observer还做了什么
- 最顶层observable发射数据后自上游向下游observer各自做了什么