1.Rxjava的基本订阅流程,上游 Observable和下游上游 Observable的概念
1.1基本概念
observable和observer通过subscribe方法实现了订阅关系,在需要的时候observable发送事件来通知observer,并且回调observer的相关方法 。
Observable:被观察者
Observer:观察者
sbscribe:订阅,将观察者和被观察者关联起来
事件:onNext,onComplete,onError
典型示例:
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) {
Log.e("TAG", "onSubscribe(): ");
}
@Override
public void onNext(String s) {
Log.e("TAG", "onNext(): " + s);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
Log.e("TAG", "onComplete(): ");
}
});
输出结果:
E/TAG: onSubscribe():
E/TAG: onNext(): 1
E/TAG: onNext(): 2
E/TAG: onNext(): 3
E/TAG: onComplete():
1.2Observable#subscribe(Observer) 订阅流程解析
直接 Observable.subscribe的源代码:
public final void subscribe(Observer<? super T> observer) {
//**********略**********
//关键代码--移步 ObservableCreate.subscribeActual
subscribeActual(observer);
//**********略**********
}
但是subscribeActual是一个抽象方法,它的具体实应该在子类中实现,到底是哪个子类可以在create方法中知道是在子类ObservableCreate中完成的:
public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
//********略
//调用hook关联方法,实际要去看ObservableCreate类
return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
}
打开ObservableCreate找到subscribeActual方法
/**
* 这里面只做了两件事:
* 1.将下游传过来的observer封装
* 2.让上游的source也就是observable来subscribe传进来的observer
**/
protected void subscribeActual(Observer<? super T> observer) {
//将observer传给observable,但是在observable中又会在onNext方法中激活observer的onNext方法。
CreateEmitter<T> parent = new CreateEmitter<T>(observer);
//方法一:触发 Observer#onSubscribe(Disposable),最先被调用的。
observer.onSubscribe(parent);
try {
//方法二:发射事件,这个方法一般是由我们自己去实现的,调用onNext和onComplete。
// source为上游observable(上游ObservableOnSubscribe的引用),
// 在所有的onservable的子类实现中都有一个source字段,指代上游observable
source.subscribe(parent);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
parent.onError(ex);
}
}
在这里需要关注source这个成员,其实它就是我们自定义的ObservableOnSubscribe赋值给它了,在所有的onservable的子类实现中都有一个source字段指代上游observable。可以看到subscribeActual里面主要有两个方法:observer.onSubscribe(parent)和source.subscribe(parent),onSubscribe很好理解,source.subscribe一般是我们自己实现的:
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
emitter.onNext("1");
emitter.onNext("2");
emitter.onNext("3");
emitter.onComplete();
}
在这里我们调用CreateEmitter的onNext和onComplete方法,跟到CreateEmitter里面看下这两个方法的具体实现
@Override
public void onNext(T t) {
//********省略
//当不处于DISPOSED状态时,会调用下游observer的onNext方法,
//下游observer就是我们自己实现的onNext回调
if (!isDisposed()) {
observer.onNext(t);
}
}
很明显这里会调用subscribeActual方法传进来的下游observer.onNext方法,其实就是我们示例中的实现的onNext。总结下:基本订阅流程是从subscribeActual开始的,将observer传递给observable,在observable中上游ObservableOnSubscribe调用subscribe时会调用onNext方法,这时候又会激活observer的onNext方法。这里面是一个链式调用,Observable#subscribeActual(Observer)实现中都包含有一句source.subscribe(Observer),其中source就是上游 Observable,所以就可以理解在每一个Observable的subscribeActual(Observer) 方法中它都会调用上游的subscribe(Observer)/subscribeActual(Observer) 方法,直至到达第一个Observable的subscribe(Observer)/subscribeActual(Observer)中。
1.3Observer#onSubscribe(Disposable) 流程
onSubscribe的过程正好和subscribe相反,当订阅到达最顶端的时候已经没办法继续往上传递了,这时候会调用最顶层observable的subscribe方法也就是subscribeActual:
CreateEmitter<T> parent = new CreateEmitter<T>(observer);
observer.onSubscribe(parent);
它首先封装了一个 Disposable,接下来将调用 Observer#onSubscribe(Disposable) 将 Disposable 作为参数传给下一层 Observer,到了下一层的Observer的onSubscribe(Disposable)中该方法中针对上一层Disposable做一些操作(判断、封装等),然后再封装一个 Disposable作为参数传递给下一层observer直至最底层,最底层的observer就是我们自己实现的。
1.4Observer#onNext(T) 流程
onNext流程跟onSubscribe比较类似,顶游Observable会触发ObservableEmitter#onNext(T)方法,在该方法的内部又触发了「下游」Observer的onNext(T) 方法,而在该方法内部又会触发「下游的下游」Observer的onNext(T)方法,直至最底层的Observer我们所自定义的 Observer。
2.Rxjava切换线程
2.1Observable#subscribeOn(Scheduler)控制线程切换
2.1.1 下游决定上游的执行线程
直接查看Observable.subscribeOn源代码
public final Observable<T> subscribeOn(Scheduler scheduler) {
// scheduler 判空
ObjectHelper.requireNonNull(scheduler, "scheduler is null");
// 用 ObservableSubscribeOn 将 scheduler 包装 起来
return RxJavaPlugins.onAssembly(new ObservableSubscribeOn<T>(this, scheduler));
}
下面我们直接跟到ObservableSubscribeOn.subscribeActual即可,遮里面同样有一个source成员类型是ObservableSource,这个类指的是上游observable,和 ObservableCreate套路是一样的。
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)));
}
//略---
}
除了source还有另外一个成员Scheduler,初始化有两种方法:Schedulers.newThread()或者Schedulers.io() 。现在重点跟进parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent))),先看看SubscribeTask这个类是ObservableSubscribeOn 的一个非静态内部类,逻辑比较简单实现了Runnable接口,并且持有parent的引用。
final class SubscribeTask implements Runnable {
private final SubscribeOnObserver<T> parent;
SubscribeTask(SubscribeOnObserver<T> parent) {
this.parent = parent;
}
@Override
public void run() {
source.subscribe(parent);
}
}
重点关注run方法,通过source.subscribe(parent)建立联系,因此当我们的SubscribeTask的run方法运行在哪个线程,相应的observer的subscribe方法就运行在哪个线程。接下来看一下scheduler.scheduleDirect这个方法:
/**
**首先,创建一个 Worker w
**第二步,DisposeTask 将 decoratedRun 包装起来
**第三步:w 去调度 task
**/
public Disposable scheduleDirect(@NonNull Runnable run, long delay, @NonNull TimeUnit unit) {
final Worker w = createWorker();
// 判断 run 是否为 null
final Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
DisposeTask task = new DisposeTask(decoratedRun, w);
w.schedule(task, delay, unit);
return task;
}
再继续跟进Worker看看里面的实现,很清晰里面就是封装了一个线程池
public Worker createWorker() {
return new NewThreadWorker(threadFactory);
}
public class NewThreadWorker extends Scheduler.Worker implements Disposable {
private final ScheduledExecutorService executor;
volatile boolean disposed;
public NewThreadWorker(ThreadFactory threadFactory) {
executor = SchedulerPoolFactory.create(threadFactory);
}
}
public static ScheduledExecutorService create(ThreadFactory factory) {
final ScheduledExecutorService exec = Executors.newScheduledThreadPool(1, factory);
if (PURGE_ENABLED && exec instanceof ScheduledThreadPoolExecutor) {
ScheduledThreadPoolExecutor e = (ScheduledThreadPoolExecutor) exec;
POOLS.put(e, exec);
}
return exec;
}
总结:
在 ObservableSubscribeOn subscribeActual 方法中, SubscribeTask 包装 parent(SubscribeOnObserver,包装了 Observer),SubscribeTask 实现了 Runnable 接口,在 run 方法里面调用了 source.subscribe(parent),因而 run 方法所执行的线程将由 worker 决定。这就是 下游决定上游 observable 执行线程的原理
2.1.2线程切换第一次有效原理
来个例子两次subscribeOn,日志:subscribe: getName=RxCachedThreadScheduler-1,如果调换两次subscribeOn的顺序日志为:subscribe: getName=RxComputationThreadPool-1
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
Log.i(TAG, "subscribe: getName=" +Thread.currentThread().getName());
}
}).subscribeOn(Schedulers.io())//第一次subscribeOn
.subscribeOn(Schedulers.computation())//第二次subscribeOn
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
Log.e("TAG", "onSubscribe(): ");
}
@Override
public void onNext(String s) {
Log.e("TAG", "onNext(): " + s);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
Log.e("TAG", "onComplete(): ");
}
});
来解释下为什么第一次subscribeOn有效,上面分析中可以知道Obsevable#subscribeOn(Scheduler)这个方法的实质其实就是将Observable#subscribe(Observer)放到指定的线程中来执行,执行Observable#subscribe的时候是自下往上的,下游observable调用上游observable,对于上面的例子流程是这样的:
(1)第三个Observable调用Observable#subscribe(Observer)启动订阅,在其内部会激活第二个Observable的Observable#subscribe(Observer)方法,但是此时该方法外部被套入了一个 Schedulers.computation() 线程
public class Observable {
// 第「二」个 Observable
Observable source;
Observer observer;
public Observable(Observable source, Observer observer) {
this.source = source;
this.observer = observer;
}
public void subscribe(Observer Observer) {
new Thread("computation") {
@Override
public void run() {
// 第「二」个 Observable 订阅
source.subscribe(observer);
}
}
}
}
(2)第二个Observable订阅内部会激活第一个Observable的Observable#subscribe(Observer)方法,同样的,该方法被套在了Schedulers.io()线程中
public class Observable {
// 第「一」个 Observable
Observable source;
Observer observer;
public Observable(Observable source, Observer observer) {
this.source = source;
this.observer = observer;
}
public void subscribe(Observer Observer) {
new Thread("io") {
@Override
public void run() {
// 第「一」个 Observable 订阅
source.subscribe(observer);
}
}
}
}
(3)第一个observable就是我们自己实现的,这里就要开始发射事件了,这两层嵌套如下可以很明显的看出为什么会第一次有效:
new Thread("computation") {
@Override
public void run() {
// 第二个 Observable.subscribe(Observer) 的实质
// 就是切换线程,效果类似如下
new Thread("io") {
@Override
public void run() {
// 第一个 Observable.subscribe(Observer) 的实质
// 就是发射事件
System.out.println("onNext(T)/onError(Throwable)/onComplete() 的执行线程是: " + Thread
.currentThread().getName());
}
} .start();
}
} .start();
2.2Observable#observeOn(Scheduler)
重述一下订阅过程:当我们调用 Observable 的 subsribe 方法的时候,会调用当前对应 observbale 的 subscribeActual 方法,在该方法里面,会调用 observer 的 onSubeciber 方法,并调用对应 ObservableOnSubscirbe 的 subcribe 的方法,并将 ObservableEmitter 作为方法参数暴露出去。而 ObservableEmitter 持有我们的 Observer 的引用,当我们调用 ObservableEmitter 的 onNext,onErrot,onComplete 方法的时候,会调用他持有的 Observer 的相应的方法。
直接看observeOn的源码:
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.create非常的类似,内部有持有上游observable的source成员,直接来看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 {
//否则,通过worker包装observer另起个线程的形式调用
Scheduler.Worker w = scheduler.createWorker();
source.subscribe(new ObserveOnObserver<T>(observer, w, delayError, bufferSize));
}
}
}
2.2.1不作用上游observable
看上面的这行代码source.subscribe(new ObserveOnObserver<T>(observer, w, delayError, bufferSize));source为上游observable,可见上游observable没有任何变化只是对下游observable进行了封装,这行代码解释了不作用上游observable。
2.2.2.作用下游observable
还是source.subscribe(new ObserveOnObserver<T>(observer, w, delayError, bufferSize));这行代码,对下游observer进行了封装成为ObserveOnObserver对象。在订阅流程中可以知道发射事件时最终会触发下游observer的onNext方法,现在跟进到ObserveOnObserver的onNext中:
public void onNext(T t) {
if (done) {
return;
}
if (sourceMode != QueueDisposable.ASYNC) {
queue.offer(t);
}
schedule();
}
做了两件事将一是传进的对象添加进队列,二是调用schedule()方法,跟进schedule方法:
void schedule() {
if (getAndIncrement() == 0) {
//这里传进去的是this,直接导致worker.schedule最终会执行
//ObserveOnObserverde的run方法。
worker.schedule(this);
}
}
schedule方法最终可以追溯到Disposable schedule(@NonNull Runnable run, long delay, @NonNull TimeUnit unit)抽象方法,找一个它的实现类IoScheduler打开它的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);
}
继续跟进threadWorker.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;
}
executor是ScheduledExecutorService实例,这个比较熟悉具有调度线程的能力。串一下流程:onNext(T)方法会触发Scheduler对象的schedule(Runnable, long, TimeUnit)方法是一个抽象方法由子类实现,所以才有了多元多样的Schedulers.io()/Schedulers.computation()/Schedulers.trampoline()等调度器。上面说过worker最终是会执行ObserveOnObserver的run方法的,回过头来看一下ObserveOnObserver的run方法:
public void run() {
if (outputFused) {
drainFused();
} else {
drainNormal();
}
}
选择一个方法的代码跟(两个比较类似)跟进drainNormal:
void drainNormal() {
int missed = 1;
final SimpleQueue<T> q = queue;
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的onNext方法(a.onNext(v)),什么意思呢,也就是说ObserveOnObserver中触发的下游observer的onNext方法在指定线程执行了,也就是达到了回调切换线程的目的了。
2.2.3举个例子说明一下
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
emitter.onNext("1");
}
})//第一个observable
.observeOn(Schedulers.io())//第二个observable
.flatMap(new Function<String, String>(){
@override
public String apply(String s) throws Exception{
return s;
}
})
.observeOn(Schedulers.computation())//第三个observable
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
Log.e("TAG", "onSubscribe(): ");
}
@Override
public void onNext(String s) {
Log.e("TAG", "onNext(): " + s);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
Log.e("TAG", "onComplete(): ");
}
});
从订阅流程可知observer的传递是从下往上的,首先observer向上传递到达第三个observable的时候进行了一次线程切换被computation 线程嵌套了一层:
public class Observer {
Observer oldObserver;
public Observer(Observer observer) {
oldObserver = observer;
}
public void onNext(T t) {
// 一些其他操作
new Thread("computation") {
@Override
public void run() {
oldObserver.onNext(t);
}
} .start();
}
public void onError(Throwable e) {
// 一些其他操作
new Thread("computation") {
@Override
public void run() {
oldObserver.onError(e);
}
} .start();
}
public void onComplete() {
// 一些其他操作
new Thread("computation") {
@Override
public void run() {
oldObserver.onComplete();
}
} .start();
}
}
observer继续向上传递到达第二个observable的时候又进行了一次切换,被io线程嵌套了一层:
public class Observer {
Observer oldObserver;
public Observer(Observer observer) {
oldObserver = observer;
}
public void onNext(T t) {
// 一些其他操作
new Thread("androidIO") {
@Override
public void run() {
oldObserver.onNext(t);
}
} .start();
}
public void onError(Throwable e) {
// 一些其他操作
new Thread("androidIO") {
@Override
public void run() {
oldObserver.onError(e);
}
} .start();
}
public void onComplete() {
// 一些其他操作
new Thread("androidIO") {
@Override
public void run() {
oldObserver.onComplete();
}
} .start();
}
}
最终到达最顶层第一个observable,简而言之 Observable#observeOn(Scheduler) 的实现原理在于将目标 Observer 的 onNext(T)/onError(Throwable)/onComplete() 置于指定线程中运行。