背景
看完记录下来踏实点
用法代码示例
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> e) throws Exception {
Log.d(TAG, "create: " + Thread.currentThread().getName());
e.onNext(1);
e.onNext(2);
}
})
.flatMap(new Function<Integer, ObservableSource<Integer>>() {
@Override
public ObservableSource<Integer> apply(Integer integer) throws Exception {
Log.d(TAG, "flatMap: " + Thread.currentThread().getName());
return Observable.just(integer);
}
})
.subscribeOn(Schedulers.io())
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Log.d(TAG, "Consumer: " + Thread.currentThread().getName());
}
});
1、创建Observable引用链
代码从上执行到下,分别会创建Observable的不同子类对象,比如ObservableObserveOn.create()会创建ObservableCreate子类对象;Observable.flatMap()会创建ObservableFlatMap子类对象,代码如下:
// Observable.create()
public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
ObjectHelper.requireNonNull(source, "source is null");
// 返回ObservableCreate,参数是ObservableOnSubscribe
return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
}
// Observable.flatMap()
public final <R> Observable<R> flatMap(Function<? super T, ? extends ObservableSource<? extends R>> mapper,
boolean delayErrors, int maxConcurrency, int bufferSize) {
...
// 返回ObservableFlatMap,参数是Function
return RxJavaPlugins.onAssembly(new ObservableFlatMap<T, R>(this, mapper, delayErrors, maxConcurrency, bufferSize));
}
需要注意的是,每个子类对象都会持有其调用者的引用,即source参数,如ObservableFlatMap的构造函数:
public ObservableFlatMap(ObservableSource<T> source,
Function<? super T, ? extends ObservableSource<? extends U>> mapper,
boolean delayErrors, int maxConcurrency, int bufferSize) {
// source即调用者Observale,如ObservableCreate.flatMap(),source就是ObservableCreate
super(source);
...
}
因此本例中,生成的对象及其引用链如下(注 —> : 表示后面持有前面):
ObservableOnSubscribe —> ObservableCreate —> ObservableFlatMap —> ObservableSubscribeOn —> ObservableSubscribeOn —> ObservableObserveOn
2、创建Observer引用链
Rxjava分观察者(Observer)和被观察者(Observable),由第一步分析可知,执行订阅(subscribe)之前只会创建引用链,而没有真正执行,真正开始执行是在调用**subscribe()**方法的时候。
订阅后发现最终会调用这个方法subscribe(Observer<? super T> observer),Consumer对象会被包裹为一个Observer(即LambdaObserver)。
public final void subscribe(Observer<? super T> observer) {
ObjectHelper.requireNonNull(observer, "observer is null");
try {
observer = RxJavaPlugins.onSubscribe(this, observer);
ObjectHelper.requireNonNull(observer, "Plugin returned null Observer");
// 抽象方法
subscribeActual(observer);
}
...
subscribeActual()是Observable的抽象方法,最终的实现要看Observable子类实现,即调用subscribe()方法的对象,本例是observeOn(AndroidSchedulers.mainThread())。即ObservableObserveOn
public final class ObservableObserveOn<T> extends AbstractObservableWithUpstream<T, T> {
@Override
protected void subscribeActual(Observer<? super T> observer) {
if (scheduler instanceof TrampolineScheduler) {
source.subscribe(observer);
} else {
Scheduler.Worker w = scheduler.createWorker();
// 调用source去执行订阅
source.subscribe(new ObserveOnObserver<T>(observer, w, delayError, bufferSize));
}
}
}
可以看到当开始订阅时,会去先执行上游Observable的订阅方法(Observable.subscribe())传入的是包裹后的Observer,如ObserveOnObserver
因此本例中,Observer引用链如下(注 <— : 表示前面持有后面):
CreateEmitter <— MergeObserver <— SubscribeOnObserver <— SubscribeOnObserver <— ObserveOnObserver <— Observer
4、执行流程
结合前两步,可得如下订阅关系:
执行流程如下:
5、线程切换
与普通的Observale不同的是,ObservableSubscribeOn和ObservableObserveOn可以用来切换线程。
5.1、消费线程
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)));
}
具体要执行的线程通过参数判断,如Schedulers.io()、Schedulers.newThread()和AndroidSchedulers.mainThread()等,分别对应IoScheduler(缓存池)、NewThreadScheduler(新线程)和HandlerScheduler(Handler主线程)。
scheduler.scheduleDirect()会根据不同的线程类型创建不同的Worker
public Disposable scheduleDirect(@NonNull Runnable run, long delay, @NonNull TimeUnit unit) {
// 创建不同的worker
final Worker w = createWorker();
final Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
DisposeTask task = new DisposeTask(decoratedRun, w);
// 执行
w.schedule(task, delay, unit);
return task;
}
//IoScheduler
public Worker createWorker() {
return new EventLoopWorker(pool.get());
}
//NewThreadScheduler
public Worker createWorker() {
return new NewThreadWorker(threadFactory);
}
//HandlerScheduler
public Worker createWorker() {
return new HandlerWorker(handler);
}
如本例中,执行线程进行了两次切换
.subscribeOn(Schedulers.io())
.subscribeOn(Schedulers.newThread())
注意到scheduler.scheduleDirect(new SubscribeTask(parent))的参数,因此最终会执行到SubscribeTask的run()方法里,可以看到也是执行了source的订阅方法。
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是subscribeOn(Schedulers.io()),会再次切换一次线程,在IoScheduler中执行SubscribeTask的run()方法。因此上游source都在IoScheduler中进行。
小结:
因为调用顺序是从下执行到上,如果连续执行线程切换,只会执行在最上流的切换线程中,下流的切换只是在别的线程中完成了上流的线程切换。
5.2、切换主线程
主线程切换发生在ObservableObserveOn的ObserveOnObserver中
public final class ObservableObserveOn<T> extends AbstractObservableWithUpstream<T, T> {
...
@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));
}
}
static final class ObserveOnObserver<T> extends BasicIntQueueDisposable<T>
implements Observer<T>, Runnable {
@Override
public void onNext(T t) {
...
// 把结果放入队列中
if (sourceMode != QueueDisposable.ASYNC) {
queue.offer(t);
}
schedule();
}
void schedule() {
if (getAndIncrement() == 0) {
// worker执行
worker.schedule(this);
}
}
}
上游的结果存放到队列中,接下来执行线程切换。
HandlerScheduler创建的Worker是HandlerWorker,具体执行如下:
private static final class HandlerWorker extends Worker {
private final Handler handler;
@Override
public Disposable schedule(Runnable run, long delay, TimeUnit unit) {
...
ScheduledRunnable scheduled = new ScheduledRunnable(handler, run);
Message message = Message.obtain(handler, scheduled);
message.obj = this; // Used as token for batch disposal of this worker's runnables.
handler.sendMessageDelayed(message, Math.max(0L, unit.toMillis(delay)));
...
}
private static final class ScheduledRunnable implements Runnable, Disposable {
private final Handler handler;
private final Runnable delegate;
private volatile boolean disposed;
ScheduledRunnable(Handler handler, Runnable delegate) {
this.handler = handler;
this.delegate = delegate;
}
@Override
public void run() {
...
delegate.run();
}
}
可以看到是用Handler发了个Message,ScheduledRunnable只是用来处理异常,最终执行的是ObserveOnObserver的run()方法,这时已经切换到了主线程
static final class ObserveOnObserver<T> extends BasicIntQueueDisposable<T>
implements Observer<T>, Runnable {
...
@Override
public void run() {
if (outputFused) {
drainFused();
} else {
drainNormal();
}
}
void drainNormal() {
int missed = 1;
final SimpleQueue<T> q = queue;
final Observer<? super T> a = actual;
for (;;) {
...
for (;;) {
boolean d = done;
T v;
v = q.poll();
boolean empty = v == null;
...
if (empty) {
break;
}
// 通知下游
a.onNext(v);
}
...
}
}
}
然后主线程里做的就是循环从队列中读取并不断调用onNext()向下游发送结果。