一、基礎知識
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方法。