RxJava 的链路调用流程
- 一、概述
- 二、基本使用方法
- 三、Observable 链路调用流程分析
- 1. testCreate() 方法的调用流程
- 2. testJust() 方法的调用流程
- 四、小结
一、概述
RxJava 是一个响应式编程框架,里面代码比较复杂,本系列文章将从以下几个角度来分析这个框架。
- RxJava 的链路调用流程。
- RxJava 的常用操作符
map、flatmap
。 - RxJava 的线程调度。
- 自己实现一个简易版的 RxJava 框架。
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
implementation 'io.reactivex.rxjava2:rxjava:2.2.19'
二、基本使用方法
我们知道, RxJava 的设计也是基于 观察者模式 的,所以里面存在两个角色,一个是观察者Observer
,另一个是被观察者Subject
。
下面我们来看看在 RxJava 中常见的构造 Subject
对象的方法。(在 RxJava 中,Subject
对应的是 Obserable、Flowable
等。
Obserable.create(ObservableOnSubscribe<T> source)
Obserable.just(T item)
Obserable.fromArray(T... items)
Obserable.zip()
...等等...
下面我们来看看 Obserable
的具体使用示例。
private void testCreate() {
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
emitter.onNext("1");
emitter.onNext("2");
emitter.onNext("3");
emitter.onComplete();
}
}).subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {}
@Override
public void onNext(String s) {
Log.d(TAG, "onNext = " + s + "; Type = " + s.getClass().getSimpleName());
}
@Override
public void onError(Throwable e) {}
@Override
public void onComplete() {
Log.d(TAG, "onComplete");
}
});
}
private void testJust() {
Observable.just("11", "22", "33")
.map(new Function<String, Integer>() {
@Override
public Integer apply(String s) throws Exception {
return Integer.parseInt(s);
}
})
.subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {}
@Override
public void onNext(Integer s) {
Log.d(TAG, "onNext = " + s + "; Type = " + s.getClass().getSimpleName());
}
@Override
public void onError(Throwable e) {}
@Override
public void onComplete() {
Log.d(TAG, "onComplete");
}
});
}
testCreate() 输出日志:
onNext = 1 ; Type = String
onNext = 2 ; Type = String
onNext = 3 ; Type = String
onComplete
testJust() 输出日志:
onNext = 11 ; Type = Integer
onNext = 22 ; Type = Integer
onNext = 33 ; Type = Integer
onComplete
下面我们就根据 testCreate()、testJust()
两个方法来分析一下 Observable 链路调用流程。
三、Observable 链路调用流程分析
下面我们先来分析一下 testCreate()
的调用链路。
1. testCreate() 方法的调用流程
testCreate()
方法主要分为两步:
- 通过
Observable.create()
方法构建一个 Observable 对象。 - 通过
Observable.subscribe()
将观察者 Observer 关联到 Observable 上。
Observable
public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
ObjectHelper.requireNonNull(source, "source is null");
// 1.这里会构建一个 ObservableCreate 类,将外部真正的数据发射源 source 保存在 ObservableCreate 中。
return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
}
// 2.调用这个 subscribe 方法的类其实是上一布创建的 ObservableCreate 类。
public final void subscribe(Observer<? super T> observer) {
ObjectHelper.requireNonNull(observer, "observer is null");
try {
observer = RxJavaPlugins.onSubscribe(this, observer);
// 3.调用 ObservableCreate.subscribeActual() 方法,这个observer是我们外部真正的接收者.
subscribeActual(observer);
} catch (NullPointerException e) { // NOPMD
// ...省略异常处理的代码...
}
}
小结:
- 调用
Observable.create()
会创建一个 ObservableCreate 对象。- 调用
ObservableCreate.subscribe()
后会触发ObservableCreate.subscribeActual()
分发,该方法会将用户创建的 Observer 和 ObservableCreate 关联起来。
下面我们看一下 ObservableCreate.subscribeActual()
方法。
ObservableCreate
public ObservableCreate(ObservableOnSubscribe<T> source) {
// 这个 source 是外部用户创建的对象。
this.source = source;
}
// 此处的接收参数 observer 是外部用户创建的接收者。
protected void subscribeActual(Observer<? super T> observer) {
// 1.将外部用户创建的接收者包装起来,返回一个包装类 CreateEmitter。
CreateEmitter<T> parent = new CreateEmitter<T>(observer);
// 2.执行接收者的 onSubscribe 方法。
observer.onSubscribe(parent);
try {
// 3.source 是外部用户创建的发射数据源,将 source 与包含有接收者的 CreateEmitter 进行关联。
source.subscribe(parent);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
parent.onError(ex);
}
}
由上面代码可知,
source
就是我们下面这段代码创建的ObservableOnSubscribe
对象。而 ObservableOnSubscribe.subscribe() 方法接收的参数就是 CreateEmitter 对象,然后我们会调用CreateEmitter.onNext()
方法。
private void testCreate() {
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
emitter.onNext("1");
emitter.onNext("2");
emitter.onNext("3");
emitter.onComplete();
}
}).subscribe(new Observer<String>() {
//略
});
}
下面我们来看一下 CreateEmitter.onNext()
方法到底做了什么?
CreateEmitter
static final class CreateEmitter<T> extends AtomicReference<Disposable>
implements ObservableEmitter<T>, Disposable {
// 这个 observer 是我们用户态创建的接收者。
final Observer<? super T> observer;
CreateEmitter(Observer<? super T> observer) {
this.observer = observer;
}
// 这个onNext方法是在用户态去触发的
@Override
public void onNext(T t) {
if (!isDisposed()) {
observer.onNext(t); //这里其实执行了用户态的observer接收者的onNext方法。
}
}
// 这个onNext方法是在用户态去触发的
@Override
public void onComplete() {
if (!isDisposed()) {
try {
//这里其实执行了用户态的observer接收者的onComplete方法。
observer.onComplete();
} finally {
dispose();
}
}
}
}
小结:
如上图所示,完整的 testCreate()
调用链路分为8个步骤:
- 在执行
Observable.create()
方法时,会先创建一个ObservableOnSubscribe
对象。- 然后通过
Observable.create()
方法会创建出一个ObservableCreate
对象。- 调用
ObservableCreate.subscribe()
方法时,会先创建一个Observer
对象。- 将步骤3创建的
Observer
对象通过ObservableCreate.subscribe()
方法赋值给ObservableCreate
对象。- 在调用
ObservableCreate.subscribe()
方法时,实际会调用ObservableCreate.subscribeActual()
方法,该方法内会创建一个CreateEmitter
对象,该对象其实是给用户调用的。- 调用
ObservableOnSubscribe.subscribe()
方法,将CreateEmitter
对象作为参数传递出去。- 用户在
ObservableOnSubscribe.subscribe()
方法中调用CreateEmitter.onNext()
方法,将数据源发射出来。- 由于
CreateEmitter
内持有用户创建的Oberver,所以在CreateEmitter.onNext()
方法中会调用Observer.onNext()
方法,完成用户的数据处理。
2. testJust() 方法的调用流程
示例代码:
private void testJust() {
Observable.just("11", "22", "33")
.map(new Function<String, Integer>() {
@Override
public Integer apply(String s) throws Exception {
return Integer.parseInt(s);
}
})
.subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Integer>() {
//略
});
}
testJust() 方法包含了以下几个操作:
- 元素的发送:
just()
操作符 - 类型的转换:
map()
操作符 - 线程的切换:
subscribeOn()、observeOn()
操作符 - 元素的接收:
subscribe()
操作符
Observable.just()
public static <T> Observable<T> just(T item1, T item2, T item3) {
// 1.接收多个事件的发送。
return fromArray(item1, item2, item3);
}
public static <T> Observable<T> fromArray(T... items) {
ObjectHelper.requireNonNull(items, "items is null");
if (items.length == 0) {
return empty();
}
if (items.length == 1) {
return just(items[0]);
}
// 2.将接收到的多个事件包装在一个ObservableFromArray中。
return RxJavaPlugins.onAssembly(new ObservableFromArray<T>(items));
}
调用
Observable.just()
方法后,返回的是 ObservableFromArray 对象。
ObservableFromArray.map()
public final <R> Observable<R> map(Function<? super T, ? extends R> mapper) {
ObjectHelper.requireNonNull(mapper, "mapper is null");
return RxJavaPlugins.onAssembly(new ObservableMap<T, R>(this, mapper));
}
调用
Observable.map()
方法后,返回的是 ObservableMap 对象,关于map
操作符的逻辑,都在 ObservableMap 对象里。
ObservableFromArray.subscribeOn()
public final Observable<T> subscribeOn(Scheduler scheduler) {
ObjectHelper.requireNonNull(scheduler, "scheduler is null");
return RxJavaPlugins.onAssembly(new ObservableSubscribeOn<T>(this, scheduler));
}
调用
Observable.subscribeOn()
方法后,返回的是 ObservableSubscribeOn 对象,关于subscribeOn
操作符的逻辑,都在 ObservableSubscribeOn 对象里。
ObservableFromArray.observeOn()
public final Observable<T> observeOn(Scheduler scheduler) {
return 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<T>(this, scheduler, delayError, bufferSize));
}
调用
Observable.observeOn()
方法后,返回的是 ObservableObserveOn 对象,关于observeOn
操作符的逻辑,都在 ObservableObserveOn 对象里。
小结:
如下图所示,完整的 testJust()
调用链路分为三个部分:
- 创建任务链。 如下图红色流程,每调用一个操作符都会返回一个与之对应的 Observable 对象。
- 逆向逐级订阅。 如下图粉色流程,每一步都会生成一个对应的 Observer 对上一步生成的Observable进行订阅。
- 执行任务链。 如下图绿色流程,执行任务链之后,每一步都会通知对应的
Observer.onNext()
,从而完成整调任务链。
四、小结
- 如何查看 RxJava 的源码?
- 学会查看 RxJava 的调用链是如何串联起来的。
- 知道每个操作符的逻辑在哪里查看。
- RxJava 的调用链是如何串联起来的?
主要通过三个流程将调用链串联起来:
- 创建任务链。 每调用一个操作符都会返回一个与之对应的 Observable 对象。
- 逆向逐级订阅。 每一步都会生成一个对应的 Observer 对上一步生成的Observable进行订阅。
- 执行任务链。 执行任务链之后,每一步都会通知对应的
Observer.onNext()
,从而完成整调任务链。
- 每个操作符的逻辑在哪里查看?
我们知道,每调用一个操作符都会返回一个与之对应的 Observable 对象。因此每个操作符的处理逻辑都写在这个新生成的 Observable 对象中,如调用
map
操作符,则该操作符的处理逻辑就在ObservableMap
中。