轉載請註明出處,謝謝https://blog.csdn.net/HarryWeasley/article/details/105363078
下方是一個最簡單切換線程的方式,本篇文章以下方的代碼引入。
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
e.onNext("1");
e.onNext("2");
e.onComplete();
}
})
//切換到子線程
.subscribeOn(Schedulers.io())
//切換主線程
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(String value) {
Log.d(TAG, "this is result"+value);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
如上的代碼,當我們調用了observeOn(AndroidSchedulers.mainThread())這句話,就切換了到主線程,現在跟着源碼看看,rxJava是如何操作的。
Observable類:
public final Observable<T> observeOn(Scheduler scheduler) {
return observeOn(scheduler, false, bufferSize());
}
public final Observable<T> observeOn(Scheduler scheduler, boolean delayError, int bufferSize) {
//檢查schedule是否爲null
ObjectHelper.requireNonNull(scheduler, "scheduler is null");
//檢查bufferSize是否大於0,默認是128
ObjectHelper.verifyPositive(bufferSize, "bufferSize");
return RxJavaPlugins.onAssembly(new ObservableObserveOn<T>(this, scheduler, delayError, bufferSize));
}
進入到RxJavaPlugins.onAssembly這個方法中
RxJavaPlugins類:
public static <T> Observable<T> onAssembly(@NonNull Observable<T> source) {
//這裏是個hook機制,onObservableAssembly默認是null
Function<? super Observable, ? extends Observable> f = onObservableAssembly;
if (f != null) {
return apply(f, source);
}
//f爲null,直接返回source,這裏是ObservableObserveOn
return source;
}
註釋已經寫明瞭,所以我們直接看傳入的ObservableObserveOn
ObservableObserveOn類:
//本例是 AndroidSchedulers.mainThread()
final Scheduler scheduler;
...
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,這裏是重點1
Scheduler.Worker w = scheduler.createWorker();
//用ObserveOnObserver訂閱上游數據源。這樣當數據從上游push下來,會由ObserveOnObserver對應的onXXX()處理
source.subscribe(new ObserveOnObserver<T>(observer, w, delayError, bufferSize));
}
}
這裏有個重點需要注意一些scheduler.createWorker(),返回了一個worker,之後會進行解釋。
現在,我們看下ObserveOnObserver類的部分方法,還是那句話,本篇文章,主要是查看如何切換到主線程的
ObserveOnObserver類:
static final class ObserveOnObserver<T> extends BasicIntQueueDisposable<T>
implements Observer<T>, Runnable {
...
@Override
public void onNext(T t) {
// 執行過error / complete 會是true
if (done) {
return;
}
// 如果數據源類型不是異步的, 默認不是
if (sourceMode != QueueDisposable.ASYNC) {
// 將上游push過來的數據 加入 queue裏
queue.offer(t);
}
//開始進入對應Workder線程,在線程裏 將queue裏的t 取出 發送給下游Observer
schedule();
}
...
void schedule() {
if (getAndIncrement() == 0) {
//將ObserveOnObserver(實現了Runnable)加入worker,這裏是重點2
worker.schedule(this);
}
}
...
}
在schedule調用了worker.schedule(this)方法,我們可以思考,在這邊將Runnable加入了worker中,那麼一定會調用其實現的run方法,而run方法裏就是主線程了。
我們去看內部調用方法:
Scheduler類:
public Disposable schedule(@NonNull Runnable run) {
return schedule(run, 0L, TimeUnit.NANOSECONDS);
}
//抽象方法,所以我們要找到實現它的類
public abstract Disposable schedule(@NonNull Runnable run, long delay, @NonNull TimeUnit unit);
這裏的schedule是AndroidSchedulers.mainThread(),那麼我們去這個類去看看,
//AndroidSchedulers類:
public static Scheduler mainThread() {
return RxAndroidPlugins.onMainThreadScheduler(MAIN_THREAD);
}
//RxAndroidPlugins類
public static Scheduler onMainThreadScheduler(Scheduler scheduler) {
if (scheduler == null) {
throw new NullPointerException("scheduler == null");
}
//其實這裏還是一個hook機制,默認這邊的onMainThreadHandler爲null
Function<Scheduler, Scheduler> f = onMainThreadHandler;
if (f == null) {
//直接返回傳入的scheduler
return scheduler;
}
return apply(f, scheduler);
}
通過上方的代碼分析,那麼直接看MAIN_THREAD是如何生成的,繼續看代碼:
//AndroidSchedulers類
private static final Scheduler MAIN_THREAD = RxAndroidPlugins.initMainThreadScheduler(
new Callable<Scheduler>() {
@Override public Scheduler call() throws Exception {
return MainHolder.DEFAULT;
}
});
//RxAndroidPlugins類:
public static Scheduler initMainThreadScheduler(Callable<Scheduler> scheduler) {
if (scheduler == null) {
throw new NullPointerException("scheduler == null");
}
//又是一個hook機制,onInitMainThreadHandler默認爲null
Function<Callable<Scheduler>, Scheduler> f = onInitMainThreadHandler;
if (f == null) {
//返回這個方法
return callRequireNonNull(scheduler);
}
return applyRequireNonNull(f, scheduler);
}
//RxAndroidPlugins類:
static Scheduler callRequireNonNull(Callable<Scheduler> s) {
try {
//這邊調用了call方法,拿到scheduler,並且返回
Scheduler scheduler = s.call();
if (scheduler == null) {
throw new NullPointerException("Scheduler Callable returned null");
}
return scheduler;
} catch (Throwable ex) {
throw Exceptions.propagate(ex);
}
}
通過 Scheduler scheduler = s.call();這個方法得知,最上面的call代碼返回的值,就是這個scheduler,就是這個MainHolder.DEFAULT。
AndroidSchedulers類:
private static final class MainHolder {
//最終的scheduler方法
static final Scheduler DEFAULT = new HandlerScheduler(new Handler(Looper.getMainLooper()));
}
可以看出來,這裏傳入了一個主線程的Handler
我們去看看HandlerScheduler類方法
HandlerScheduler類:
final class HandlerScheduler extends Scheduler {
//主線程的handler
private final Handler handler;
HandlerScheduler(Handler handler) {
this.handler = handler;
}
...
@Override
public Worker createWorker() {
//這裏不就是重點1,調用的方法嗎,所以worker就是HandlerWorker
return new HandlerWorker(handler);
}
}
從上面的代碼,我們終於找到了worker的實現類了,我們找到了worker類,那麼我們就去找重點2的那個方法,看實現的schedule(@NonNull Runnable run, long delay, @NonNull TimeUnit unit)的具體實現代碼。
去看HandlerWorker的實現方法
//HandlerWorker類
public Disposable schedule(Runnable run, long delay, TimeUnit unit) {
...
hook機制,其實就是獲取到run
run = RxJavaPlugins.onSchedule(run);
//一個代理類,其實還是一個實現的Runnable的類
ScheduledRunnable scheduled = new ScheduledRunnable(handler, run);
//獲取到message,將scheduled賦值到callBack裏
Message message = Message.obtain(handler, scheduled);
message.obj = this; // Used as token for batch disposal of this worker's runnables.
//handler發送消息,delay是0
handler.sendMessageDelayed(message, unit.toMillis(delay));
...
return scheduled;
}
//Message類
public static Message obtain(Handler h, Runnable callback) {
Message m = obtain();
m.target = h;
//給message的callback賦值上面的Runnable
m.callback = callback;
return m;
}
上面的代碼,獲取到一個message,然後直接通過handler發送消息,這個handler之前已經說過,是一個主線程Looper.getMainLooper()的handler。其實之後,就是handler機制了的,最終主線程的Looper循環,獲取到message信息,最終會調用handler的dispatchMessage方法。
public void dispatchMessage(@NonNull Message msg) {
//這裏已經是主線程了
if (msg.callback != null) {
//之前將其callback賦值了,所以會執行此地方的代碼
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
//這裏不就是我們正常情況下,自定義handler處理代碼的地方嗎
handleMessage(msg);
}
}
private static void handleCallback(Message message) {
//從這裏可以看到,調用了callback的run方法
message.callback.run();
}
這裏可以自己敲代碼驗證一下,例子如下:
case R.id.btn10:
//button點擊後,發送一個消息
Handler handler = new Handler(Looper.getMainLooper());
myRunnable runnable = new myRunnable();
Message message = Message.obtain(handler, runnable);
handler.sendMessage(message);
break;
...
class myRunnable implements java.lang.Runnable {
@Override
public void run() {
Log.d(TAG, "這裏執行了" + Thread.currentThread());
}
}
執行結果爲:這裏執行了Thread[main,5,main]
從上面的代碼知道,就是傳入的message的callback執行了run方法,callback就是代理類ScheduledRunnable,那我們看下他的run方法
private static final class ScheduledRunnable implements Runnable, Disposable {
@Override
public void run() {
try {
//這裏已經是主線程了
//這裏的delegate就是重點2傳入的Runnable,也就是ObserveOnObserver
delegate.run();
} catch (Throwable t) {
RxJavaPlugins.onError(t);
}
}
}
從上面的代碼中,可知,通過消息機制,已經進入了主線程,這個時候,再調用ObserveOnObserver的run方法,我們繼續看代碼
static final class ObserveOnObserver<T> extends BasicIntQueueDisposable<T>
implements Observer<T>, Runnable {
...
@Override
public void run() {
//從這裏開始,這個方法已經是在Workder對應的線程裏執行的了
//默認是false
if (outputFused) {
drainFused();
} else {
drainNormal();
}
}
...
void drainNormal() {
int missed = 1;
final SimpleQueue<T> q = queue;
final Observer<? super T> a = actual;
for (;;) {
// 如果已經 終止 或者queue空,則跳出函數,
if (checkTerminated(done, q.isEmpty(), a)) {
return;
}
for (;;) {
boolean d = done;
T v;
try {
//從queue裏取出一個值
v = q.poll();
} catch (Throwable ex) {
//異常處理 並跳出函數
Exceptions.throwIfFatal(ex);
s.dispose();
q.clear();
a.onError(ex);
worker.dispose();
return;
}
...
//發送給下游了
a.onNext(v);
}
...
}
}
}
從上面,就看出來了,在下游的onNext方法裏,已經變成了主線程了。
總結:
- ObserveOnObserver實現了Observer和Runnable接口。
- 在onNext()裏,先不切換線程,將數據加入隊列queue。然後開始切換線程,在另一線程中,從queue裏取出數據,push給下游Observer
- 所以observeOn()影響的是其下游的代碼,且多次調用仍然生效。
- 因爲其切換線程代碼是在Observer裏onXXX()做的,這是一個主動的push行爲(影響下游)。
- 關於多次調用生效問題,observeOn()是一個主動的行爲,每次切換線程後會立刻發送數據,在OnXXX()方法裏執行代碼,所以會生效多次.
- 最終能切換到主線程,是通過消息機制,主線程的looper一直循環獲取MessageQueue的message消息,然後調用他的callback.run方法
這樣整個切換到主線程的流程已經分析完了。之後的文章,我準備再分析下切換子線程的流程,其實流程是大同小異的。
本篇文章結束。