1.先来一段最基本的调用
// 创建上游被观察者
Observable observable = Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter e) throws Exception {
Log.i(TAG, "ObservableEmitter, 上游发射数据:" + " currentThread = " + Thread.currentThread().getName());
e.onNext(1);// 调用Observer的onNext
e.onComplete();// 调用Observer的onComplete
}
});
// 创建下游观察者
Observer observer = new Observer() {
@Override
public void onSubscribe(Disposable d) {
// onSubscribe在调用subscribe的线程中执行
// Disposable可以做切断操作,让Observer不再接收上游事件
Log.i(TAG, "onSubscribe, 下游收到订阅,发生在上游发射数据之前: " + " currentThread = " + Thread.currentThread().getName());
}
@Override
public void onNext(Integer integer) {
Log.i(TAG, "onNext, 下游接收数据: " + " currentThread = " + Thread.currentThread().getName());
}
@Override
public void onError(Throwable e) {
Log.i(TAG, "onError, 下游收到异常: " + " currentThread = " + Thread.currentThread().getName());
}
@Override
public void onComplete() {
Log.i(TAG, "onComplete, 调用结束: " + " currentThread = " + Thread.currentThread().getName());
}
};
// 订阅
observable.subscribe(observer);
日志打印如下:
I/RxJava2: onSubscribe, 下游收到订阅,发生在上游发射数据之前: currentThread = main
I/RxJava2: ObservableEmitter, 上游发射数据: currentThread = main
I/RxJava2: onNext, 下游接收数据: currentThread = main
I/RxJava2: onComplete, 调用结束: currentThread = main
可以看出:
- 下游观察者onSubscribe方法首先执行;
- 然后上游被观察者的subscribe方法执行;
- 最后下游观察者的onNext、onComplete执行。
分析一下这个过程,Observable.create创建了Observable对象,也就是ObservableCreate
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
public static Observable create(ObservableOnSubscribe source) {
ObjectHelper.requireNonNull(source, "source is null");
return RxJavaPlugins.onAssembly(new ObservableCreate(source));// 钩子函数,直接返回ObservableCreate
}
调用subscribe时就调用了ObservableCreate的subscribe方法,ObservableCreate继承了Observable,就相当于调用了父类的subscribe方法,看一下Observable的subscribe方法
public abstract class Observable implements ObservableSource {
...
@SchedulerSupport(SchedulerSupport.NONE)
@Override
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这个抽象方法
} catch (NullPointerException e) { // NOPMD
throw e;
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
// can't call onError because no way to know if a Disposable has been set or not
// can't call onSubscribe because the call might have set a Subscription already
RxJavaPlugins.onError(e);
NullPointerException npe = new NullPointerException("Actually not, but can't throw other exceptions due to RS");
npe.initCause(e);
throw npe;
}
}
protected abstract void subscribeActual(Observer super T> observer);// 抽象方法,子类实现
...
}
这样就回到了ObservableCreate这个实现类,重点关注它的subscribeActual实现方法
public final class ObservableCreate extends Observable {
final ObservableOnSubscribe source;
public ObservableCreate(ObservableOnSubscribe source) {
this.source = source;// 这是传入的就是我们create创建的匿名内部类ObservableOnSubscribe
}
@Override
protected void subscribeActual(Observer super T> observer) {// 传入观察者
// 创建了CreateEmitter,这是一个静态内部类,它实现了ObservableEmitter和Disposable接口,就是上游发射数据的发射器
CreateEmitter parent = new CreateEmitter(observer);
observer.onSubscribe(parent);// 这里就调用了下游观察者的onSubscribe方法,所以日志打印时Observer的onSubscribe最先调用
try {
source.subscribe(parent);// 这里调用了ObservableOnSubscribe的subscribe方法,用来发射数据
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
parent.onError(ex);
}
}
static final class CreateEmitter extends AtomicReference
implements ObservableEmitter, Disposable {
private static final long serialVersionUID = -3434801548987643227L;
final Observer super T> observer;
CreateEmitter(Observer super T> observer) {// 传入我们创建的下游观察者
this.observer = observer;
}
@Override
public void onNext(T t) {// 当上游调用e.onNext时,调用此方法
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()) {// 没被切断操作
observer.onNext(t);// 调动了observer的onNext方法
}
}
@Override
public void onError(Throwable t) {// 当异常时调用此方法
if (!tryOnError(t)) {
RxJavaPlugins.onError(t);
}
}
@Override
public boolean tryOnError(Throwable t) {
if (t == null) {
t = new NullPointerException("onError called with null. Null values are generally not allowed in 2.x operators and sources.");
}
if (!isDisposed()) {
try {
observer.onError(t);// 调用observer的onError方法
} finally {
dispose();
}
return true;
}
return false;
}
@Override
public void onComplete() {// 当上游调用e.onComplete时,调用此方法
if (!isDisposed()) {
try {
observer.onComplete();// 调用observer的onComplete方法
} finally {
dispose();
}
}
}
...
}
...
}
上面就展示了最基本的从上游到下游中间的调用过程。
2.增加线程切换
先上代码
observable.subscribeOn(Schedulers.io())// 用于指定subscribe时所在的线程,就是发射事件的线程(指定多次,第一次为准)
.observeOn(AndroidSchedulers.mainThread())// 用于指定下游Observer回调发生的线程,就是订阅者接收事件的线程。(可以指定多次)
.subscribe(observer);
日志打印如下:
I/RxJava2: onSubscribe, 下游收到订阅,发生在上游发射数据之前: currentThread = main
I/RxJava2: ObservableEmitter, 上游发射数据: currentThread = RxCachedThreadScheduler-1
I/RxJava2: onNext, 下游接收数据: currentThread = main
I/RxJava2: onComplete, 调用结束: currentThread = main
可以看出:
- 下游观察者onSubscribe方法执行在subscribe时的线程;
- 上游被观察者的subscribe方法(也就是发射数据时的方法)执行在RxCachedThreadScheduler-1线程;
- 下游观察者的onNext、onComplete都执行在主线程。
2.1现在分析线程切换的原理,首先看subscribeOn方法,返回了ObservableSubscribeOn
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.CUSTOM)
public final Observable subscribeOn(Scheduler scheduler) {
ObjectHelper.requireNonNull(scheduler, "scheduler is null");
// this就是observable,scheduler就是传入的Schedulers.io
return RxJavaPlugins.onAssembly(new ObservableSubscribeOn(this, scheduler));
}
继续看ObservableSubscribeOn,它继承了AbstractObservableWithUpstream
public final class ObservableSubscribeOn extends AbstractObservableWithUpstream {
final Scheduler scheduler;
public ObservableSubscribeOn(ObservableSource source, Scheduler scheduler) {
super(source);// 1.保存上游的observable
this.scheduler = scheduler;// 2.保存传入的线程调度器
}
@Override
public void subscribeActual(final Observer super T> s) {
// 3.对下游Observer进行装饰
final SubscribeOnObserver parent = new SubscribeOnObserver(s);
// 4.首先调用下游observer的onSubscribe方法
s.onSubscribe(parent);
// 5.SubscribeTask是一个runnable,scheduler在指定的线程运行这个runnable,再将线程调度的Disposable赋值给当前的Disposable
// 这里就实现了线程的切换了,run方法运行在scheduler的线程
parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)));
}
static final class SubscribeOnObserver extends AtomicReference implements Observer, Disposable {
private static final long serialVersionUID = 8094547886072529208L;
final Observer super T> actual;
final AtomicReference s;
SubscribeOnObserver(Observer super T> actual) {
this.actual = actual;// 保存下游的observer
this.s = new AtomicReference();
}
@Override
public void onSubscribe(Disposable s) {
DisposableHelper.setOnce(this.s, s);
}
@Override
public void onNext(T t) {
actual.onNext(t);// 通过装饰的SubscribeOnObserver,最终调用下游observer的onNext方法
}
@Override
public void onError(Throwable t) {
actual.onError(t);
}
@Override
public void onComplete() {
actual.onComplete();
}
...
}
final class SubscribeTask implements Runnable {
private final SubscribeOnObserver parent;
SubscribeTask(SubscribeOnObserver parent) {
this.parent = parent;// 保存下游observer的装饰对象
}
@Override
public void run() {
// 6.这里就在指定的scheduler线程调用下游装饰后的observer订阅上游observable的方法,
// 相当于上面没有线程切换的状态,只是observer变成了装饰后的SubscribeOnObserver,
// 调用的方法onSubscribe、onNext等就到了SubscribeOnObserver那,最终调用下游observer的
source.subscribe(parent);
}
}
}
这里可以总结一下大致的流程
- 调用subscribeOn时,将Obserable装饰成ObservableSubscribeOn,将Observer装饰成SubscribeOnObserver;在最初subscribe订阅的线程回调observer的onSubscribe方法;
- 然后调用parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)))执行runnable实现线程切换,在scheduler线程run方法调用source.subscribe(parent),这里的parent SubscribeOnObserver就是装饰后的observer,最终调用observer的方法。
Scheduler的scheduleDirect方法
public abstract class Scheduler {
...
@NonNull
public Disposable scheduleDirect(@NonNull Runnable run) {// 这里传入的就是SubscribeTask
return scheduleDirect(run, 0L, TimeUnit.NANOSECONDS);
}
@NonNull
public Disposable scheduleDirect(@NonNull Runnable run, long delay, @NonNull TimeUnit unit) {
// 这里的子类就是IoScheduler,创建的worker是EventLoopWorker
final Worker w = createWorker();
// hook方法,可以认为decoratedRun == run
final Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
// DisposeTask 实现了Runnable, Disposable
DisposeTask task = new DisposeTask(decoratedRun, w);
// 这里最终掉用了ThreadWorker的scheduleActual方法,切换到线程池中执行
w.schedule(task, delay, unit);
return task;
}
@NonNull
public abstract Worker createWorker();// 抽象方法,子类实现
...
}
AbstractObservableWithUpstream
abstract class AbstractObservableWithUpstream extends Observable implements HasUpstreamObservableSource {
/** The source consumable Observable. */
protected final ObservableSource source;// Observable是ObservableSource实现类,所以可以看成是Observable
/**
* Constructs the ObservableSource with the given consumable.
* @param source the consumable Observable
*/
AbstractObservableWithUpstream(ObservableSource source) {
this.source = source;// 构造方法,ObservableSubscribeOn中会调用
}
@Override
public final ObservableSource source() {
return source;
}
}
AbstractObservableWithUpstream继承了Observable,通过source保存上游的Observable。
2.2再看observeOn方法
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.CUSTOM)
public final Observable observeOn(Scheduler scheduler) {
return observeOn(scheduler, false, bufferSize());
}
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.CUSTOM)
public final Observable observeOn(Scheduler scheduler, boolean delayError, int bufferSize) {
ObjectHelper.requireNonNull(scheduler, "scheduler is null");
ObjectHelper.verifyPositive(bufferSize, "bufferSize");
return RxJavaPlugins.onAssembly(new ObservableObserveOn(this, scheduler, delayError, bufferSize));
}
到这里可以猜想流程跟subscribeOn
差不多,都是采用装饰者模式,分别对Observable
跟Observer
装饰产生一个中间的被观察者和观察者,实现线程变换。
继续看ObservableObserveOn
,这也是对Observable
的装饰,它也继承了AbstractObservableWithUpstream
public final class ObservableObserveOn extends AbstractObservableWithUpstream {
final Scheduler scheduler;
final boolean delayError;
final int bufferSize;
public ObservableObserveOn(ObservableSource source, Scheduler scheduler, boolean delayError, int bufferSize) {
super(source);// 1.保存上游装饰过的observable
this.scheduler = scheduler;// 2.保存传入的线程调度器
this.delayError = delayError;
this.bufferSize = bufferSize;
}
@Override
protected void subscribeActual(Observer super T> observer) {
if (scheduler instanceof TrampolineScheduler) {
source.subscribe(observer);
} else {
// 3.这里的子类就是HandlerScheduler,创建HandlerWorker
Scheduler.Worker w = scheduler.createWorker();
// 4.装饰下游observer,调用上游装饰的observable的subscribe方法
// 上游observable执行subscribeActual,调用ObserveOnObserver的onSubscribe、onNext等方法
source.subscribe(new ObserveOnObserver(observer, w, delayError, bufferSize));
}
}
}
ObserveOnObserver的静态内部类ObserveOnObserver,上游observable执行subscribeActual方法,调用ObserveOnObserver的onSubscribe、onNext等方法
static final class ObserveOnObserver extends BasicIntQueueDisposable
implements Observer, Runnable {
private static final long serialVersionUID = 6576896619930983584L;
final Observer super T> actual;
final Scheduler.Worker worker;
final boolean delayError;
final int bufferSize;
SimpleQueue queue;
Disposable s;
Throwable error;
volatile boolean done;
volatile boolean cancelled;
int sourceMode;
boolean outputFused;
ObserveOnObserver(Observer super T> actual, Scheduler.Worker worker, boolean delayError, int bufferSize) {
this.actual = actual;// 下游observer
this.worker = worker;// 调度工作者
this.delayError = delayError;
this.bufferSize = bufferSize;
}
@Override
public void onSubscribe(Disposable s) {
if (DisposableHelper.validate(this.s, s)) {
this.s = s;
if (s instanceof QueueDisposable) {// 一般为true
@SuppressWarnings("unchecked")
QueueDisposable qd = (QueueDisposable) s;
int m = qd.requestFusion(QueueDisposable.ANY | QueueDisposable.BOUNDARY);
if (m == QueueDisposable.SYNC) {// 判断执行模式同步或者异步
sourceMode = m;
queue = qd;
done = true;// 标志为true,后面的onxx不会执行,直接return
actual.onSubscribe(this);
schedule();
return;
}
if (m == QueueDisposable.ASYNC) {
sourceMode = m;
queue = qd;
actual.onSubscribe(this);// 调用下游observer的onSubscribe
return;
}
}
queue = new SpscLinkedArrayQueue(bufferSize);
actual.onSubscribe(this);
}
}
@Override
public void onNext(T t) {
if (done) {// 判断是否完成
return;
}
if (sourceMode != QueueDisposable.ASYNC) {
queue.offer(t);
}
schedule();// 开始调度
}
@Override
public void onError(Throwable t) {// 只执行一次
if (done) {// 判断是否完成
RxJavaPlugins.onError(t);
return;
}
error = t;// 记录错误
done = true;// 标志为true
schedule();// 开始调度
}
@Override
public void onComplete() {
if (done) {// 判断是否完成
return;
}
done = true;// 标志为true
schedule();// 开始调度
}
...
}
最终都调用了schedule方法,实现线程的切换
void schedule() {
if (getAndIncrement() == 0) {
worker.schedule(this);
}
}
这里传入了this,因为ObserveOnObserver实现了Runnable接口,看它的run方法
@Override
public void run() {
if (outputFused) {// 一般是false
drainFused();
} else {
drainNormal();
}
}
看drainNormal方法
void drainNormal() {
int missed = 1;
final SimpleQueue 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);// 下发数据给下游observer
}
missed = addAndGet(-missed);
if (missed == 0) {
break;
}
}
}
// 检查是否已终止
boolean checkTerminated(boolean d, boolean empty, Observer super T> a) {
if (cancelled) {// 已取消
queue.clear();// 清空队列
return true;
}
if (d) {// 这里是done
Throwable e = error;
if (delayError) {
if (empty) {
if (e != null) {
a.onError(e);
} else {
a.onComplete();
}
worker.dispose();
return true;
}
} else {
if (e != null) {
queue.clear();
a.onError(e);
worker.dispose();
return true;
} else
if (empty) {
a.onComplete();
worker.dispose();
return true;
}
}
}
return false;
}
总结
- 创建任务链,每一步都会返回对应的Observable对象;
- 逆向逐级订阅,每一步都会生成对应的Observer对上一步生成的Observable进行订阅;
- 执行任务链,执行任务链之后,每一步都会通知对应的Observer,从而完成整调任务链。