上一篇中看了Rxjava的通过链式调用来实现数据的传输,这一篇接着看加上线程切换之后,整个流程是怎样的。
还是以下面这个流程为例:
Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter emitter) throws Exception {
emitter.onNext("数据");
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(String s) {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
通过上一篇我们可以知道,Observable.create()之后返回的是一个ObservableCreate对象,而ObservableCreate对象是继承自Observable对象。所以create之后,实际上是Observable.subscribeOn(Schedulers.io()),同样的它返回一个继承了Observable的对象。关于链式调用这一块这里就不再做详细的说明了。
这里的重点是包括线程切换在内的整个的流程是怎样的,以上面的代码块为例,今天我们要搞懂,数据在传输过程中到底经历了什么。
这里我们先记录一下每个操作返回的对象
操作 | 返回的Observable对象 |
---|---|
Observable.create() | ObservableCreate对象 |
Observable.subscribeOn(Schedulers.io()) | ObservableSubscribeOn对象 |
Observable.observeOn(AndroidSchedulers.mainThread()) | ObservableObserveOn对象 |
Observable. subscribe(Observer对象) |
ObservableCreate、ObservableSubscribeOn、ObservableObserveOn都是继承自Observable,并且实现了subscribeActual(Observer observer) 方法(调用Observable.subscribe(Observer) 最终都会调用该方法)
通过断点调试,我们可以发现上面的这几个对象最终都调用了各自的subscribeActual,而且调用的顺序是从下到上的(它们的创建顺序是从上到下的)。这里我就直接上图了,贴上我自己的理解:
对照上图我们具体来看一下,当走到Observable. subscribe(Observer对象)这一步的时候,实际上是D:ObservableObserveOn.subscribe(Observer对象),而且会把上一层的Observable(这里是C:ObservableSubscribeOn对象)作为source(构造函数里的参数)传入D中,之前说过,调用subscribe方法,都会调用各自的subscribeActual方法,
在ObservableObserveOn的subscribeActual方法中:
protected void subscribeActual(Observer super T> observer) {
if (scheduler instanceof TrampolineScheduler) {
source.subscribe(observer);
} else {
Scheduler.Worker w = scheduler.createWorker();
source.subscribe(new ObserveOnObserver(observer, w, delayError, bufferSize));
}
}
如果在同一个线程,就可以直接订阅observer,如果不在同一个线程,就需要用之前传入的指定线程,并将订阅的操作指定在该线程中。这里的source就是作为构造函数参数传入D的C。这里相当于又调用了C.subscribe,经历的流程和上面的过程差不多。
这里的核心思想都是上一个Observable作为下一个的Observable的一部分,当下层的Observable开始调用subscribe方法之后,其实是会调用上一层的Observable的subscribe方法,经过这样一层一层的递归,最终会到最初create这里。
同理,一开始订阅的时候,传入的是一个Observer对象的引用,经过一层一层的将这个对象传入或者封装之后再传入。这样就实现了数据上下游的连通。
最后看一下线程切换
subscribeOn(Schedulers.io())
最终进入的是ObservableSubscribeOn对象中
public void subscribeActual(final Observer super T> s) {
final SubscribeOnObserver parent = new SubscribeOnObserver(s);
s.onSubscribe(parent);
parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)));
}
这边scheduler是之前传入的Schedulers.io(),新建了一个订阅的线程:
final class SubscribeTask implements Runnable {
private final SubscribeOnObserver parent;
SubscribeTask(SubscribeOnObserver parent) {
this.parent = parent;
}
@Override
public void run() {
source.subscribe(parent);
}
}
这里另起了一个线程执行订阅操作
再来看看observeOn(AndroidSchedulers.mainThread())
protected void subscribeActual(Observer super T> observer) {
if (scheduler instanceof TrampolineScheduler) {
source.subscribe(observer);
} else {
Scheduler.Worker w = scheduler.createWorker();
source.subscribe(new ObserveOnObserver(observer, w, delayError, bufferSize));
}
}
这里如果是同一个线程,就不用再切换了,如果不是同一个线程,需要创建一个新的。
到这里Rxjava基本流程就看的差不多了,其他的就算换一些操作符,本质上的流程还是一样的(Flowable可能有点区别)