参考文章
在分析线程切换源码之前有必要分析订阅流程。
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> e) throws Exception {
e.onNext(100);
e.onNext(200);
e.onComplete();
}
}).subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Integer integer) {
Log.e("shenkai", "onNext:" + integer);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
Log.e("shenkai", "onComplete: ");
}
});
先分析创建流程,Observable#create是把我们传进去的ObservableOnSubscribe对象包装成ObservableCreate对象并返回。如下图:
再看调用subscribe方法,subscribe中调用了subscribeActual,它是个抽象方法,此时的子类是ObservableCreate对象,看ObservableCreate#subscribeActual:
protected void subscribeActual(Observer<? super T> observer) {
CreateEmitter<T> parent = new CreateEmitter<T>(observer);
observer.onSubscribe(parent);
source.subscribe(parent);
}
第一步把观察者Observer包装成CreateEmitter对象,第二步调用observer.onSubscribe(parent);并把CreateEmitter对象传进去,第三部的source是我们创建的ObservableOnSubscribe对象,CreateEmitter是ObservableEmitter的实现类,当我们调用emitter.onNext时会调用observer的onNext,具体就不贴代码了。
static final class CreateEmitter<T>
extends AtomicReference<Disposable>
implements ObservableEmitter<T>, Disposable {
接下来分析线程切换,先分析subscribeOn方法
new Thread() {
@Override
public void run() {
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> e) throws Exception {
Log.e(TAG, "subscribe: " + Thread.currentThread());
e.onNext(100);
e.onNext(200);
e.onComplete();
}
})
.subscribeOn(Schedulers.io())
.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {
Log.e(TAG, "onSubscribe: " + Thread.currentThread());
}
@Override
public void onNext(Integer integer) {
Log.e(TAG, "onNext: " + Thread.currentThread());
Log.e(TAG, "onNext:" + integer);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
Log.e(TAG, "onComplete: ");
}
});
}
}.start();
Observable#subscribeOn是把调用subscribeOn方法的被观察者包装成ObservableSubscribeOn,这里调用subscribeOn的被观察者是ObservableCreate对象。
public final Observable<T> subscribeOn(Scheduler scheduler) {
ObjectHelper.requireNonNull(scheduler, "scheduler is null");
return RxJavaPlugins.onAssembly(new ObservableSubscribeOn<T>(this, scheduler));
}
从订阅流程可知Observable#subscribe会调用子类的subscribeActual,我们看看ObservableSubscribeOn#subscribeActual方法吧:
@Override
public void subscribeActual(final Observer<? super T> s) {
final SubscribeOnObserver<T> parent = new SubscribeOnObserver<T>(s);
s.onSubscribe(parent);
parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)));
}
第一步是把我们传进去的观察者包装成SubscribeOnObserver,第二步调用观察者的onSubscribe方法,第三步首先是把SubscribeOnObserver包装成SubscribeTask对象,
final class SubscribeTask implements Runnable {
private final SubscribeOnObserver<T> parent;
SubscribeTask(SubscribeOnObserver<T> parent) {
this.parent = parent;
}
@Override
public void run() {
source.subscribe(parent);
}
}
这里的source是ObservableCreate对象。
接着看scheduler.scheduleDirect,
public Disposable scheduleDirect(@NonNull Runnable run, long delay, @NonNull TimeUnit unit) {
final Worker w = createWorker();
final Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
//把任务和worker包装成DisposeTask
DisposeTask task = new DisposeTask(decoratedRun, w);
//把DisposeTask交给worker调度
w.schedule(task, delay, unit);
return task;
}
createWorker是个抽象方法,这里的子类实现是
IoScheduler#createWorker
public Worker createWorker() {
return new EventLoopWorker(pool.get());
}
接着看EventLoopWorker#schedule:
public Disposable schedule(@NonNull Runnable action, long delayTime, @NonNull TimeUnit unit) {
if (tasks.isDisposed()) {
// don't schedule, we are unsubscribed
return EmptyDisposable.INSTANCE;
}
return threadWorker.scheduleActual(action, delayTime, unit, tasks);
}
NewThreadWorker#scheduleActual
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) {
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;
}
实际上就是把任务交给线程池执行,也就是说SubscribeTask#run方法中的代码都会在线程池执行。也就是发射事件的代码和观察者中执行的代码都在线程池中执行了,这样就完成了线程切换。subscribeOn多次调用只有第一次有效,这是为什么呢?
.subscribeOn(Schedulers.io())
.subscribeOn(Schedulers.computation())
.subscribeOn(AndroidSchedulers.mainThread())
因为每调用一次subscribeOn就把上游的Observable包装成ObservableSubscribeOn对象,来看看这个对象的创建
public final class ObservableSubscribeOn<T> extends AbstractObservableWithUpstream<T, T> {
final Scheduler scheduler;
public ObservableSubscribeOn(ObservableSource<T> source, Scheduler scheduler) {
super(source);
this.scheduler = scheduler;
}
@Override
public void subscribeActual(final Observer<? super T> s) {
final SubscribeOnObserver<T> parent = new SubscribeOnObserver<T>(s);
s.onSubscribe(parent);
parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)));
}
...
}
scheduler.scheduleDirect(new SubscribeTask(parent))所做的事情是指定上一层Observable#subscribe执行在本层指定的线程。直到顶层Observable也就是ObservableCreate#subscribe被执行,它执行所在的线程当然就是离他最近的subscribeOn,本例是subscribeOn(Schedulers.io())。
总结:subscribeOn多次调用只有第一次有效原因看上图第三次调用会执行第二层被包装被观察者的subscribe方法,第二层又会调用第一层被包装的subscribe方法,通过这样层层调用最终我们传递进去的ObservableOnSubscribe的subscribe方法执行的线程就是离他最近调用的subscribeOn方法参数所在的线程。
Observable#observeOn
new Thread() {
@Override
public void run() {
Log.e("TAG", "当前线程环境:" + Thread.currentThread().getName());
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
e.onNext("A");
e.onComplete();
}
})
// .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
Log.e("TAG", "onSubscribe线程环境:" + Thread.currentThread().getName());
}
@Override
public void onNext(String s) {
Log.e("TAG", "onNext线程环境:" + Thread.currentThread().getName());
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
}
}.start();
Observable#observeOn是把上游Observable和scheduler包装为ObservableObserveOn对象并返回。
new ObservableObserveOn<T>(this, scheduler, delayError, bufferSize)
看看ObservableObserveOn的构造方法和subscribeActual方法。
public final class ObservableObserveOn<T> extends AbstractObservableWithUpstream<T, T> {
final Scheduler scheduler;
final boolean delayError;
final int bufferSize;
public ObservableObserveOn(ObservableSource<T> source, Scheduler scheduler, boolean delayError, int bufferSize) {
super(source);
this.scheduler = scheduler;
this.delayError = delayError;
this.bufferSize = bufferSize;
}
@Override
protected void subscribeActual(Observer<? super T> observer) {
if (scheduler instanceof TrampolineScheduler) {
source.subscribe(observer);
} else {
Scheduler.Worker w = scheduler.createWorker();
source.subscribe(new ObserveOnObserver<T>(observer, w, delayError, bufferSize));
}
}
...
}
在subscribeActual方法else语句中调用上游被观察者的subscribe方法,注意此时并没有切换线程,也就是说Observable#observeOn并不会改变上游的执行线程。接着把观察者包装成ObserveOnObserver对象。我们看看ObserveOnObserver对象的onNext方法:
public void onNext(T t) {
if (sourceMode != QueueDisposable.ASYNC) {
queue.offer(t);
}
schedule();
}
void schedule() {
if (getAndIncrement() == 0) {
worker.schedule(this);
}
}
public void run() {
if (outputFused) {//默认为false
drainFused();
} else {
drainNormal();
}
}
void drainNormal() {
int missed = 1;
final SimpleQueue<T> q = queue;
final Observer<? super T> a = actual;//被包装的观察者
for (;;) {
if (checkTerminated(done, q.isEmpty(), a)) {
return;
}
for (;;) {
boolean d = done;
T v;
try {
v = q.poll();
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
s.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;
}
}
}
这样就把观察者的onNext方法置于指定的线程中执行了。
简而言之new ObserveOnObserver(observer, w, delayError, bufferSize)这行代码内部实现是w开线程执行observer,每调用一次observerOn都开启指定线程执行下游观察者,这就达到了每次调用observerOn都对下游有效。