我们先以下面的demo为例,来解释Rxjava的整个工作流程。
public void start() {
Observable<Integer> observable1 = Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
Log.d(TAG, "当前线程名称 " + Thread.currentThread().getName());
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
emitter.onComplete();
}
});
Observer<Integer> observer = new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "开始采用subscribe连接 " + Thread.currentThread().getName());
}
@Override
public void onNext(Integer value) {
Log.d(TAG, "观察者线程在 " + Thread.currentThread().getName());
Log.d(TAG, "对Next事件作出响应" + value);
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "对Error事件作出响应");
}
@Override
public void onComplete() {
Log.d(TAG, "对Complete事件作出响应");
}
};
observable1
.subscribeOn(Schedulers.newThread())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.observeOn(Schedulers.newThread())
.subscribe(observer);
subscribe前的操作符
@SchedulerSupport(SchedulerSupport.CUSTOM)
public final Observable<T> subscribeOn(Scheduler scheduler) {
ObjectHelper.requireNonNull(scheduler, "scheduler is null");
return RxJavaPlugins.onAssembly(new ObservableSubscribeOn<T>(this, scheduler));
}
- 第一个操作符.subscribeOn(Observable.java)
@SchedulerSupport(SchedulerSupport.CUSTOM)
public final Observable<T> subscribeOn(Scheduler scheduler) {
ObjectHelper.requireNonNull(scheduler, "scheduler is null");
return RxJavaPlugins.onAssembly(new ObservableSubscribeOn<T>(this, scheduler));
}
ObservableSubscribeOn继承 AbstractObservableWithUpstream,是对Observable的包装
此时,执行完new ObservableSubscribeOn之后, Observable的结构如下
- 第二个操作符.subscribeOn(Observable.java)
其基本执行流程同上,只是Scheduler不一样,那么还是对
Observable的进一步包装,此时,执行完new ObservableSubscribeOn之后,Observable的结构如下
- 第三个操作符.observeOn(Observable.java)
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.CUSTOM)
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再次包装成 ObservableObserveOn
public ObservableObserveOn(ObservableSource<T> source, Scheduler scheduler, boolean delayError, int bufferSize) {
super(source);
this.scheduler = scheduler;
this.delayError = delayError;
this.bufferSize = bufferSize;
}
此时,执行完new ObservableObserveOn, Observable的结构如下
- 第四个操作符.observeOn(Observable.java)
和第三步执行一样,只是将第三步的Observable继续包装,那么执行完的Observable机构如下
总结一下: 在调用Subscribe之前的操作符都是对Observable的包装,那么最里层的Observable就是demo里的observable1了。
subscribe流程
这里需要注意的是,每一个操作符都都对应了一个静态内部类的Observer,操作符向下包装Observable,向上订阅过程中用对应的静态内部类包装Observer,理解这一点非常重要。
.subscribe(observer);
这里的observer就是在程序中实际声明的observer,接下来看下具体的订阅流程
public final void subscribe(Observer<? super T> observer) {
ObjectHelper.requireNonNull(observer, "observer is null");
try {
subscribeActual 的具体执行者就是上述中最后的包装的Observable,ObservableObserveOn
subscribeActual(observer);
}
}
- 接下来看下ObservableObserveOn的subscribeActual方法都干了什么
@Override
protected void subscribeActual(Observer<? super T> observer) {
if (scheduler instanceof TrampolineScheduler) {
source.subscribe(observer);
} else {
//scheduler 为最后生成时的NewThreadScheduler
Scheduler.Worker w = scheduler.createWorker();
// 对observer的第一次包装
source.subscribe(new ObserveOnObserver<T>(observer, w, delayError, bufferSize));
}
}
可以看到对定义的observer和worker进行一次包装
ObserveOnObserver(Observer<? super T> actual, Scheduler.Worker worker, boolean delayError, int bufferSize) {
this.downstream = actual;
this.worker = worker;
this.delayError = delayError;
this.bufferSize = bufferSize;
}
- 那么现在的Observer的结构是这个样子的
source.subscribe(new ObserveOnObserver<T>(observer, w, delayError, bufferSize));
此时的source对应的是ObservableSubscribeOn,如图下所示
@Override
public void subscribeActual(final Observer<? super T> observer) {
final SubscribeOnObserver<T> parent = new SubscribeOnObserver<T>(observer);
observer.onSubscribe(parent);
parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)));
此过程对Observer再次包装,
结构如下,如红框所示
observer.onSubscribe(parent);随后传入的downstream(ObserveOnObserver)执行onSubscribe(parent),parent是SubscribeOnObserver
@Override
public void onSubscribe(Disposable d) {
if (DisposableHelper.validate(this.upstream, d)) {
this.upstream = d;
** if条件不执行**
if (d instanceof QueueDisposable) {
@SuppressWarnings("unchecked")
QueueDisposable<T> qd = (QueueDisposable<T>) d;
int m = qd.requestFusion(QueueDisposable.ANY | QueueDisposable.BOUNDARY);
if (m == QueueDisposable.SYNC) {
sourceMode = m;
queue = qd;
done = true;
downstream.onSubscribe(this);
schedule();
return;
}
if (m == QueueDisposable.ASYNC) {
sourceMode = m;
queue = qd;
downstream.onSubscribe(this);
return;
}
}
queue = new SpscLinkedArrayQueue<T>(bufferSize);
执行这个downstream,这个downstream 还是个ObserveOnObserver,
downstream.onSubscribe(this);
}
}
看上方注释,会再次调用ObserveOnObserver的onSubscribe方法,这里比较绕,需要画图才能清晰的理解。那么与上一次执行不同的是,此时的 if (d instanceof QueueDisposable)是满足条件的,因为此时d是ObserveOnObserver,而ObserveOnObserver继承了BasicIntQueueDisposable,所以这个if条件满足
static final class ObserveOnObserver<T> extends BasicIntQueueDisposable<T>`
因为本次执行结果不一样,所以再把代码发下
@Override
public void onSubscribe(Disposable d) {
if (DisposableHelper.validate(this.upstream, d)) {
this.upstream = d;
1. 满足条件,进入if语句
if (d instanceof QueueDisposable) {
@SuppressWarnings("unchecked")
QueueDisposable<T> qd = (QueueDisposable<T>) d;
int m = qd.requestFusion(QueueDisposable.ANY | QueueDisposable.BOUNDARY);
if (m == QueueDisposable.SYNC) {
sourceMode = m;
queue = qd;
done = true;
downstream.onSubscribe(this);
schedule();
return;
}
3.经过计算 符合此条件,执行downstream的onSubscribe方法,退出
if (m == QueueDisposable.ASYNC) {
sourceMode = m;
queue = qd;
downstream.onSubscribe(this);
return;
}
}
queue = new SpscLinkedArrayQueue<T>(bufferSize);
downstream.onSubscribe(this);
}
}
2. 在这个Observer中outputFused设置为true,后面会用到
@Override
public int requestFusion(int mode) {
if ((mode & ASYNC) != 0) {
outputFused = true;
return ASYNC;
}
return NONE;
}
看上面的注释3,那么这个downstream其实就是我们程序中实际写的Observer了,也就是
Observer<Integer> observer = new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "开始采用subscribe连接 " + Thread.currentThread().getName());
}
所以,这里有个结论就是,Observer的onSubscire不受线程切换的限制,只和调用处的线程有关,因为执行到现在线程仍然在调用处的县城里。
会到4处,执行完Subscribe,我们看下面
parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)));
根据函数的名字能够猜到这里就是线程切换的地方。我们跟进一下代码。
1). SubscribeTask 实现了Runnable接口,并且保存了Observer
final class SubscribeTask implements Runnable {
private final SubscribeOnObserver<T> parent;
SubscribeTask(SubscribeOnObserver<T> parent) {
this.parent = parent;
}
@Override
public void run() {
source.subscribe(parent);
}
}
2)scheduler.scheduleDirec(xx)
@NonNull
public Disposable scheduleDirect(@NonNull Runnable run) {
return scheduleDirect(run, 0L, TimeUnit.NANOSECONDS);
}
@NonNull
public Disposable scheduleDirect(@NonNull Runnable run, long delay, @NonNull TimeUnit unit) {
1. 这个Scheduler是个IoScheduler,这里返回一个IoScheduler的静态内部类型EventLoopWorker
final Worker w = createWorker();
final Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
2. 对传入的SubscribeTask进行包装,DisposeTask 也实现了Runnable接口
DisposeTask task = new DisposeTask(decoratedRun, w);
3.执行worker的schedule方法
w.schedule(task, delay, unit);
return task;
}
继续跟进EventLoopWorker.java
public Disposable schedule(@NonNull Runnable action, long delayTime, @NonNull TimeUnit unit) {
if (tasks.isDisposed()) {
// don schedule, we are unsubscribed
return EmptyDisposable.INSTANCE;
}
这里threadWorker是NewThreadWorker
return threadWorker.scheduleActual(action, delayTime, unit, tasks);
}
这里threadWorker是NewThreadWorker
跟进NewThreadWorke.java
/**
* Wraps the given runnable into a ScheduledRunnable and schedules it
* on the underlying ScheduledExecutorService.
* <p>If the schedule has been rejected, the ScheduledRunnable.wasScheduled will return
* false.
* @param run the runnable instance
* @param delayTime the time to delay the execution
* @param unit the time unit
* @param parent the optional tracker parent to add the created ScheduledRunnable instance to before it gets scheduled
* @return the ScheduledRunnable instance
*/
@NonNull
public ScheduledRunnable scheduleActual(final Runnable run, long delayTime, @NonNull TimeUnit unit, @Nullable DisposableContainer parent) {
Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
ScheduledRunnable sr = new ScheduledRunnable(decoratedRun, parent);
if (parent != null) {
if (!parent.add(sr)) {
return sr;
}
}
Future<?> f;
try {
if (delayTime <= 0) {
这里的executor是 ScheduledExecutorService executor;
f = executor.submit((Callable<Object>)sr);
} else {
f = executor.schedule((Callable<Object>)sr, delayTime, unit);
}
sr.setFuture(f);
} catch (RejectedExecutionException ex) {
if (parent != null) {
parent.remove(sr);
}
RxJavaPlugins.onError(ex);
}
return sr;
}
- 所以线程就是在这里发生了切换,通过ScheduledExecutorService执行任务,那么这个任务是谁呢?就是一路传过来的
SubsribeTask, 执行其run方法,也就是source.subscribe(parent);
总结一下就是,ObservableSubscribeOn的方法继续将下游的Observer进行包装,然后切换线程,在新的线程中继续执行订阅,并将包装后的Observer继续传给上游。
- 那个由上述的结论推理下一个source,也就是ObservableSubscribeOn,还将继续执行上述过程,线程切换到Schedulers.newThread()中,这里就不再重复跟进了,直接在SubscribeTask的run方法中继续跟进.
- 由4可知,此时的也就是ObservableSubscribeOn执行完,此时source是也就是ObservableSubscribeOn的上游,也就是原始的source了,也就是
ObservableCreate了
public final class ObservableCreate<T> extends Observable<T> {
final ObservableOnSubscribe<T> source;
public ObservableCreate(ObservableOnSubscribe<T> source) {
this.source = source;
}
@Override
protected void subscribeActual(Observer<? super T> observer) {
1. 将oberver传入,包装成CreateEmitter
CreateEmitter<T> parent = new CreateEmitter<T>(observer);
observer.onSubscribe(parent);
try {
2. 执行真正的订阅方法
source.subscribe(parent);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
parent.onError(ex);
}
}
Observable<Integer> observable1 = Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
3. 真正的执行的地方
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
Log.d(TAG, "当前线程名称 " + Thread.currentThread().getName());
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
emitter.onComplete();
}
});
总结一下: 最终的被观察者所在的线程是在第一个SubscribeOn中设置的线程中执行的,所以subscribeOn多次切换线程虽然每次都生效,但是最后发送数据的是以第一个为准的。
以onNext为例,分析ObserveOn流程
- CreateEmitter的onNext
@Override
public void onNext(T t) {
if (t == null) {
onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources."));
return;
}
if (!isDisposed()) {
1. 这个observer是上个source对应的静态内部类SubscribeOnObserver
observer.onNext(t);
}
}
- SubscribeOnObserver的onNext
@Override
public void onNext(T t) {
这个downstream是下一个SubscribeOnObserver
downstream.onNext(t);
}
- 根据上面的注释,会重复执行2的过程,此处省略,那么执行完后,这个downstream是谁呢,是ObserveOnObserver了,所以会执行ObserveOnObserver的onNext方法.
@Override
public void onNext(T t) {
if (done) {
return;
}
1.将数据存入queue中
if (sourceMode != QueueDisposable.ASYNC) {
queue.offer(t);
}
2.线程切换的地方
schedule();
}
void schedule() {
if (getAndIncrement() == 0) {
3.执行worker的schedule方法,这个worker是谁呢,是HandlerWorker
worker.schedule(this);
}
}
- 所以在次进行线程切换,然后执行当前Observer的run方法
@Override
public void run() {
1. 上面分析过outputFused 会为true,所以执行drainFused
if (outputFused) {
drainFused();
} else {
drainNormal();
}
}
void drainFused() {
int missed = 1;
for (;;) {
if (disposed) {
return;
}
boolean d = done;
Throwable ex = error;
if (!delayError && d && ex != null) {
disposed = true;
downstream.onError(error);
worker.dispose();
return;
}
2. 执行下游的downstream的onNext方法,这个downstream是谁? 还是ObserveOnObserver
downstream.onNext(null);
if (d) {
disposed = true;
ex = error;
if (ex != null) {
downstream.onError(ex);
} else {
downstream.onComplete();
}
worker.dispose();
return;
}
missed = addAndGet(-missed);
if (missed == 0) {
break;
}
}
}
- 根据上面注释2,再次执行线程切换,执行run方法
@Override
public void run() {
1. 通步骤4不同的是,这时的outputFused是false,所以执行drainNormal()方法
if (outputFused) {
drainFused();
} else {
drainNormal();
}
}
void drainNormal() {
int missed = 1;
final SimpleQueue<T> q = queue;
2. 这个downstream是谁?这个就是我们具体声明的Observer啦
final Observer<? super T> a = downstream;
for (;;) {
if (checkTerminated(done, q.isEmpty(), a)) {
return;
}
for (;;) {
boolean d = done;
T v;
try {
v = q.poll();
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
disposed = true;
upstream.dispose();
q.clear();
a.onError(ex);
worker.dispose();
return;
}
boolean empty = v == null;
if (checkTerminated(d, empty, a)) {
return;
}
if (empty) {
break;
}
a.onNext(v);
}
missed = addAndGet(-missed);
if (missed == 0) {
break;
}
}
}
Observer<Integer> observer = new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "开始采用subscribe连接 " + Thread.currentThread().getName());
}
3. 执行此方法
@Override
public void onNext(Integer value) {
Log.d(TAG, "观察者线程在 " + Thread.currentThread().getName());
Log.d(TAG, "对Next事件作出响应" + value);
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "对Error事件作出响应");
}
@Override
public void onComplete() {
Log.d(TAG, "对Complete事件作出响应");
}
};
总结一下,虽然obserseOn线程可以指定多次,但是最终程序中声明的observer执行线程是在最后的observeOn的线程中执行的。
综合所述:
- 自上而下的每一个操作符都是对上游observerable的一次包装,生成新的Observable
- 执行subscribe后,相当于回溯调用上游的Observable的订阅流程,是对上游的Observable拆解,也是对下游的Observer的一次包装,在此过程中对subscribeOn中的线程切换,但是最终的Observable是在第一次切换的线程中
- 最终Observable执行onNext的方法时是对Observer的拆解,同时还进行了线程切换,最终observer的执行是在最后一次observeOn指定的线程中进行的