本文为博主原创文章,转载请注明出处
前言
本文简析 RxJava2
的 subscribeOn
和 zip
操作符。
术语解释
Single.just().map().flatMap().subscribeOn().observeOn().subscribe();
上述代码中,Single
到 subscribe()
之间的都称为 操作符
,想像一下自己就是其中一个 操作符
,那么位于左边的便称为 上游
,位于右边的则称为 下游
,故上下游其实是相对的。
源码分析指南
由于 RxJava
是链式调用,链条长度没有限制,所以源码分析需要技巧,直接从头看到尾,容易看的头晕。所以建议先写一个『最短的调用链』去分析,然后举一反三,推测其设计思想(仔细想想就知道,那么多操作符,肯定不需要每个都去分析,也不现实,所以只要理解其设计思想就行了)。
首先,我们需要明确每一次操作符调用的返回类型是什么:subscribe()
左边都是观察者的上游,而观察者的上游肯定是被观察者。所以每一次操作符调用的返回类型都是被观察者(而且每次都返回一个新的被观察者,内部持有对上一个观察者的引用)。鉴于 RxJava
的被观察者类型较多,有:
-
io.reactivex.Flowable
: 0..N flows, supporting Reactive-Streams and backpressure -
io.reactivex.Observable
: 0..N flows, no backpressure, -
io.reactivex.Single
: a flow of exactly 1 item or an error, -
io.reactivex.Completable
: a flow without items but only a completion or error signal, -
io.reactivex.Maybe
: a flow with no items, exactly one item or an error.
背压:上游数据发射太快,下游来不及处理,导致缓冲区溢出(类比我国人民都知道的水缸进水、放水问题)
本文仅以 io.reactivex.Single
为例进行分析,其他类型举一反三即可,此处先给出对象引用关系图,根据此图即可推出函数调用轨迹:
![2722938-c9b33acd78765c79.jpg](https://upload-images.jianshu.io/upload_images/2722938-c9b33acd78765c79.jpg)
源码分析都写在注释里了,subscribeOn
操作符是对 java 并发框架和 Android Handler 的封装,zip
操作符则是利用 java 原子类实现的。
一、subscribeOn
demo
// Case2: 在非UI线程执行并关注结果
Single.fromCallable(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return generateRandom();
}
}).subscribeOn(Schedulers.io()).subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Logger.d(TAG, "test: accept(Integer integer) invoked on %s", Thread.currentThread().getName());
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
Logger.d(TAG, "test: accept(Throwable throwable) invoked on %s", Thread.currentThread().getName());
}
});
fromCallable(Callable callable) [-> Single.java]
public static <T> Single<T> fromCallable(final Callable<? extends T> callable) {
ObjectHelper.requireNonNull(callable, "callable is null");
// RxJavaPlugins 里是全局钩子函数,分析源码时无视即可,此处就是返回 SingleFromCallable
return RxJavaPlugins.onAssembly(new SingleFromCallable<T>(callable));
}
RxJavaPlugins
里是全局钩子函数,无需关注
SingleFromCallable [-> SingleFromCallable.java]
// 注意继承自 Single,而 Single 实现了 SingleSource 接口,所以也继承了 subscribe() 方法
public final class SingleFromCallable<T> extends Single<T> {
// 回调函数
final Callable<? extends T> callable;
public SingleFromCallable(Callable<? extends T> callable) {
// 保存为全局变量
this.callable = callable;
}
@Override
protected void subscribeActual(SingleObserver<? super T> observer) {
// 一个 run() 方法体为空的 RunnableDisposable 对象,用来取消订阅
Disposable d = Disposables.empty();
// 调用下游(本示例此处为SubscribeOnObserver)的 onSubscribe()
observer.onSubscribe(d);
// 已取消订阅的,直接返回,不会发射任何值
if (d.isDisposed()) {
return;
}
T value;
try {
// 调用 callable.call() 获取值
value = ObjectHelper.requireNonNull(callable.call(), "The callable returned a null value");
} catch (Throwable ex) {
// 捕获所有异常,所以使用 rxjava 时,自己写的方法收不到异常通知,需订阅一个 Consumer<Throwable>
Exceptions.throwIfFatal(ex);
if