RxJavaPlugins.onAssembly(new SingleJust
这个方法的作用设什么呢,其实它的作用就是一个转换作用。使用的hook技术,这里原理比较难懂 暂时理解成会转换成 new出来的对象吧。
/**
* Calls the associated hook function.
* @param the value type
* @param source the hook's input value
* @return the value returned by the hook
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
@NonNull
public static Single onAssembly(@NonNull Single source) {
Function super Single, ? extends Single> f = onSingleAssembly;
if (f != null) {
return apply(f, source);
}
return source;
}
Single.just("1")
.subscribe(new SingleObserver() {
@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 方法被调用。
Single.just("1")
.map(new Function() {
@Override
public Integer apply(String s) throws Exception {
return Integer.valueOf(s);
}
})
.subscribe(new SingleObserver() {
@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, 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() {
@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(s, scheduler));
// source 是SingleSubscribeOn
}
//这是SingleSubscribeOn处理订阅的方法
protected void subscribeActual(final SingleObserver super T> s) {
final SubscribeOnObserver parent = new SubscribeOnObserver(s, source);
s.onSubscribe(parent);
// 执行了线程切换,至于怎么线程切换先暂时不要关注,只是测试的parent ,如果在此订阅就是另外一个线程了,可以简单理解把parent 丢到另一个线程中了,执行了run方法
Disposable f = scheduler.scheduleDirect(parent);
parent.task.replace(f);
}
// 对应的查看SubscribeOnObserver 的run方法
static final class SubscribeOnObserver
extends AtomicReference
implements SingleObserver, 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 对应的 SingleSubscribeOn 被观察者的订阅方法
protected void subscribeActual(final SingleObserver super T> s) {
final SubscribeOnObserver parent = new SubscribeOnObserver(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
贴一下SubscribeOnObserver 的run方法
static final class SubscribeOnObserver
extends AtomicReference
implements SingleObserver, Disposable, Runnable {
@Override
public void run() {
//source 就是 SingleJust实例对象
source.subscribe(this);
}
}
至此,subscribeOn 切换了订阅线程。 简单说让上一层的订阅在线程中执行。
observeOn 控制的是回调执行的线程,也就是 onSucess 或者 map操作符对应的函数方法执行的线程。
observeOn 对应的被观察者是 SingleObserveOn 对应的观察者是ObserveOnSingleObserver 所以我们直接去看看一下它的回调方法是如何执行的。
static final class ObserveOnSingleObserver extends AtomicReference
implements SingleObserver, 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方法。