一、基础知识
RxJavaPlugins.onAssembly(new SingleJust<T>(item));
这个方法的作用设什么呢,其实它的作用就是一个转换作用。使用的hook技术,这里原理比较难懂 暂时理解成会转换成 new出来的对象吧。
/**
* Calls the associated hook function.
* @param <T> the value type
* @param source the hook's input value
* @return the value returned by the hook
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
@NonNull
public static <T> Single<T> onAssembly(@NonNull Single<T> source) {
Function<? super Single, ? extends Single> f = onSingleAssembly;
if (f != null) {
return apply(f, source);
}
return source;
}
二、最简单的调用
Single.just("1")
.subscribe(new SingleObserver<String>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onSuccess(String s) {
}
@Override
public void onError(Throwable e) {
}
});
这段代码很简单的调用,里面的逻辑就是 Single.just 会产生一个SingleJust 对象然后调用父类的 subscribe 方法,在这个方法中最终还是调用的自己的subscribeActual 方法, 这个方法的参数是 SingleObserver 。
protected void subscribeActual(SingleObserver<? super T> s) {
s.onSubscribe(Disposables.disposed());
s.onSuccess(value);
}
最后得到结果就是SingleObserver 的onSubscribe 和 onSuccess 方法被调用。
三、加点难度 加入Map操作符以后是怎么调用呢?
Single.just("1")
.map(new Function<String, Integer>() {
@Override
public Integer apply(String s) throws Exception {
return Integer.valueOf(s);
}
})
.subscribe(new SingleObserver<Integer>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onSuccess(Integer integer) {
}
@Override
public void onError(Throwable e) {
}
});
看看这个是如何回调成功呢?
首先还是创建一个SingleJust 调用map操作符,返回一个SingleMap 对象,然后调用去subscribe订阅 SingleObserver ,最终方法往回调用,到达 SingleMap 的 subscribeActual 并传入观察者对象SingleObserver。
source.subscribe(new MapSingleObserver<T, R>(t, mapper));
这里的source 是SingleJust , t是SingleObserver 对象 ,mapper 是map操作符传入的一个函数方法。
接下来看SingleJust的subscribe 如何调用的? 依然是父类的 subscribeActual传入的参数是 MapSingleObserver
最终调用了
protected void subscribeActual(SingleObserver<? super T> s) {
s.onSubscribe(Disposables.disposed());
s.onSuccess(value);
}
跟上一步一样调用了这个方法,只不过这里的观察者是MapSingleObserver。 看看它的onSubscribe 和 onSuccess 做了些什么事。
public void onSuccess(T value) {
R v;
try {
v = ObjectHelper.requireNonNull(mapper.apply(value), "The mapper function returned a null value.");
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
onError(e);
return;
}
t.onSuccess(v);
}
显示调用mapper的apply方法 也就是map 的那个转换操作的方法。 转换以后的值 作为的t的onSuccess 参数。也就是SingleObserver的onSuccess 被调用了。
小结一下:
1、从上到下调用过程中不停包装被观察者,显示SingleJust 然后到 SingleMap,soure就是自己上一层对象的引用
2、当遇到subscribe是 就一次调用每个被观察这的订阅功能, 显示SingleMap.subscribe(SingleObserver) 然后 把SingleObserver包装成MapSingleObserver 交给SingleJust 订阅, 一直到数据源位置,调用对象的onSubscribe ,onSuccess
3、从数据源 在一次调用每个被包装的 observer的onsuccess 方法,直到最后的 SingleObserver 的方法被调用
套路就是被观察者 (Single、Observable)没遇到一个操作符都把自己包装一层,然后用source 记录上一层的引用, 知道遇到subscribe 订阅方法,会创建一个观察者SingleObserver, 然后内部一次包装上一层的被观察这对象需要订阅的观察者。 如 SingleMap 订阅 SingleObserver,然后 SingleJust 订阅 MapSingleObserver 。 最后 调用终点的数据源的回调方法,onSuccess 。 在一次回调每一层的Observer 方法直到调用结束。
四、再加一点难度,加上线程操作符
Single.just("1")
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new SingleObserver<String>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onSuccess(String integer) {
}
@Override
public void onError(Throwable e) {
}
});
为了理解起来不那么吃力,将map操作符暂时先去掉。
第一步 和第二步
根据 前面两节总结的套路,每次遇到操作符就创建对应的一个包裹被观察者,所以subscribeOn操作符 创建了 SingleSubscribeOn被观察者 ,然后 observeOn 创建了 SingleObserveOn被观察者。他们分别订阅了下一级穿过来的观察者。
SingleObserveOn 订阅了 SingleObserver, 并包装了一个 ObserveOnSingleObserver
// 这是SingleObserveOn 处理订阅的方法
protected void subscribeActual(final SingleObserver<? super T> s) {
source.subscribe(new ObserveOnSingleObserver<T>(s, scheduler));
// source 是SingleSubscribeOn
}
//这是SingleSubscribeOn处理订阅的方法
protected void subscribeActual(final SingleObserver<? super T> s) {
final SubscribeOnObserver<T> parent = new SubscribeOnObserver<T>(s, source);
s.onSubscribe(parent);
// 执行了线程切换,至于怎么线程切换先暂时不要关注,只是测试的parent ,如果在此订阅就是另外一个线程了,可以简单理解把parent 丢到另一个线程中了,执行了run方法
Disposable f = scheduler.scheduleDirect(parent);
parent.task.replace(f);
}
// 对应的查看SubscribeOnObserver 的run方法
static final class SubscribeOnObserver<T>
extends AtomicReference<Disposable>
implements SingleObserver<T>, Disposable, Runnable {
...//一些其他的方法
@Override
public void run() {
source.subscribe(this);
//在线程中完成了订阅
}
}
按照订阅的执行顺序.subscribe -> observeOn -> subscribeOn -> just, 所以先是SingleObserveOn 订阅 SingleObserver,把SingleObserver包装成ObserveOnSingleObserver,交给SingleSubscribeOn订阅(启动了一个线程,在run方法中完成的订阅),并在包装一层得到一个 ObserveOnSingleObserver 交给 SingleJust进行 回调。
可以看到observeOn中并没有做任何操作,而subscribeOn 执行了一些特殊的代码。scheduler.scheduleDirect(parent)
注释中我已经说明清楚。 所以到了SingleJust 数据源回调的时候,就是在newthread 线程中执行的。
第三步
执行从数据源开始执行回调,首页是SingleJust执行了onSuccess方法。 看一下 subscribeOn操作符创建被观察者SingleSubscribeOn 对应的观察者 ObserveOnSingleObserver的回调方法如何执行呢?
SubscribeOnObserver(SingleObserver<? super T> actual, SingleSource<? extends T> source)
this.actual = actual;
this.source = source;
this.task = new SequentialDisposable();
}
@Override
public void onSubscribe(Disposable d) {
DisposableHelper.setOnce(this, d);
}
@Override
public void onSuccess(T value) {
actual.onSuccess(value);
}
@Override
public void onError(Throwable e) {
actual.onError(e);
}
这里的actual就是它的下一层 observeOn创建的被观察者 SingleObserveOn 对应的观察者 ObserveOnSingleObserver 执行回调方法了
ObserveOnSingleObserver(SingleObserver<? super T> actual, Scheduler scheduler) {
this.actual = actual;
this.scheduler = scheduler;
}
@Override
public void onSubscribe(Disposable d) {
if (DisposableHelper.setOnce(this, d)) {
actual.onSubscribe(this);
}
}
@Override
public void onSuccess(T value) {
//value 是从数据源一步步会掉回来的值
this.value = value;
//同样是完成了线程切换 但是它并没有执行下一步操作的回调。 如果不回调等于链条就断了,所以一定有回调,假设一下,线程切换执行就会在 run方法中执行回调
Disposable d = scheduler.scheduleDirect(this);
DisposableHelper.replace(this, d);
}
@Override
public void onError(Throwable e) {
this.error = e;
Disposable d = scheduler.scheduleDirect(this);
DisposableHelper.replace(this, d);
}
@Override
public void run() {
Throwable ex = error;
if (ex != null) {
actual.onError(ex);
} else {
//完成了线程操作以后, 执行run方法,然后继续回调
actual.onSuccess(value);
//actual 是 observeOn 创建的 SingleObserver ,至此我们就得到了想要的结果,回调链结束
}
}
observeOn 的 onSuccess 方法中切换了线程 在对应的 run方法中完成的下一层的回调
actual 是 observeOn 创建的 SingleObserver ,至此我们就得到了想要的结果,回调链结束。
分析subscribeOn 和 observeOn是如何完成线程切换的
subscribeOn 对应的 SingleSubscribeOn 被观察者的订阅方法
protected void subscribeActual(final SingleObserver<? super T> s) {
final SubscribeOnObserver<T> parent = new SubscribeOnObserver<T>(s, source);
s.onSubscribe(parent);
//parent作为一个
Disposable f = scheduler.scheduleDirect(parent);
parent.task.replace(f);
}
public Disposable scheduleDirect(@NonNull Runnable run, long delay, @NonNull TimeUnit unit) {
final Worker w = createWorker();
final Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
DisposeTask task = new DisposeTask(decoratedRun, w);
w.schedule(task, delay, unit);
return task;
}
从代码上看它创建了一个worker 然后执行了schedule , 因为我们newThread 对应是NewThreadWorker(猜的),看看它的schedule执行了什么。
public ScheduledRunnable scheduleActual(final Runnable run, long delayTime, @NonNull TimeUnit unit, @Nullable DisposableContainer parent) {
//run 就是 前面的parent 它是一个观察者(SubscribeOnObserver),
Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
//继续对这个 Runnable进行包装
ScheduledRunnable sr = new ScheduledRunnable(decoratedRun, parent);
if (parent != null) {
if (!parent.add(sr)) {
return sr;
}
}
Future<?> f;
try {
if (delayTime <= 0) {
// 最后执行了submit
// executor == private final ScheduledExecutorService executor;
// 执行了线程池 ,所以SubscribeOnObserver 的run就会被调用
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;
}
贴一下SubscribeOnObserver 的run方法
static final class SubscribeOnObserver<T>
extends AtomicReference<Disposable>
implements SingleObserver<T>, Disposable, Runnable {
@Override
public void run() {
//source 就是 SingleJust实例对象
source.subscribe(this);
}
}
至此,subscribeOn 切换了订阅线程。 简单说让上一层的订阅在线程中执行。
observeOn 控制的是回调执行的线程,也就是 onSucess 或者 map操作符对应的函数方法执行的线程。
observeOn 对应的被观察者是 SingleObserveOn 对应的观察者是ObserveOnSingleObserver 所以我们直接去看看一下它的回调方法是如何执行的。
static final class ObserveOnSingleObserver<T> extends AtomicReference<Disposable>
implements SingleObserver<T>, Disposable, Runnable {
ObserveOnSingleObserver(SingleObserver<? super T> actual, Scheduler scheduler) {
this.actual = actual;
this.scheduler = scheduler;
}
// 删掉了一些对于的方法
@Override
public void onSuccess(T value) {
this.value = value;
// 执行了线程操作,根据subscribeOn操作符的经验,这一句代码,主要是为了执行this 的润方法, 而run方法中正好是执行了对应的回调方法。
Disposable d = scheduler.scheduleDirect(this);
DisposableHelper.replace(this, d);
}
@Override
public void run() {
Throwable ex = error;
if (ex != null) {
actual.onError(ex);
} else {
actual.onSuccess(value);
}
}
}
看看scheduler.scheduleDirect
public Disposable scheduleDirect(@NonNull Runnable run, long delay, @NonNull TimeUnit unit) {
final Worker w = createWorker();
final Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
DisposeTask task = new DisposeTask(decoratedRun, w);
w.schedule(task, delay, unit);
return task;
}
一模一样的代码,创建一个worker 然后执行schedule,如何执行的?因为使用的是 AndroidSchedulers.mainThread() 所以对应的 Worker 猜测是HandlerScheduler 看看它的schedule
public Disposable schedule(Runnable run, long delay, TimeUnit unit) {
if (run == null) throw new NullPointerException("run == null");
if (unit == null) throw new NullPointerException("unit == null");
if (disposed) {
return Disposables.disposed();
}
run = RxJavaPlugins.onSchedule(run);
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, unit.toMillis(delay));
// Re-check disposed state for removing in case we were racing a call to dispose().
if (disposed) {
handler.removeCallbacks(scheduled);
return Disposables.disposed();
}
return scheduled;
}
是不是特别熟悉 handler.sendMessageDelayed 发送消息到主线程去执行(猜的)。
看看 AndroidSchedulers.mainThread() 创建是什么 Scheduler DEFAULT = new HandlerScheduler(new Handler(Looper.getMainLooper()));
主线程的handler 的包裹对象。
这个包裹对象被扔给了SingleObserveOn 被观察者,然后传递给了它对应的观察者 ObserveOnSingleObserver 最终执行了
public Disposable scheduleDirect(@NonNull Runnable run, long delay, @NonNull TimeUnit unit) {
final Worker w = createWorker();
final Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
DisposeTask task = new DisposeTask(decoratedRun, w);
w.schedule(task, delay, unit);
return task;
}
HandlerScheduler
public Worker createWorker() {
return new HandlerWorker(handler);
}
所以最后实质就是调用了MainHandler的run方法。