目前RxJava已經被廣泛用於Android開發中,GitHub地址在這,官方文檔說2018.03.31停止維護1.x 版本,本篇文章基於RxJava 1.2.2
。
關於RxJava
的介紹文章推薦看扔物線的給 Android 開發者的 RxJava 詳解,這篇文章講解了很多使用方法、結論和部分原理,雖然是兩年前的文章,但現在看還是有不少的收穫。
常用的類和接口
在正式開始分析之前,我們先來回顧一下RxJava
中常用的一些類和接口,以利於後面的分析。
被觀察者-類Observable,RxJava
中核心的類,事件的生產者,它的大量操作符可以將一個Observable
轉換爲另一個Observable
。它有一個成員變量onSubscribe
。
public class Observable<T> {
final OnSubscribe<T> onSubscribe;
public interface OnSubscribe<T> extends Action1<Subscriber<? super T>> {
// cover for generics insanity
}
}
觀察者-接口Observer,事件的消費者。
public interface Observer<T> {
void onCompleted();
void onError(Throwable e);
void onNext(T t);
}
訂閱-接口Subscription,被觀察者和觀察者形成訂閱關係後,就有返回一個訂閱,便於取消訂閱。
public interface Subscription {
void unsubscribe();
boolean isUnsubscribed();
}
訂閱者-抽象類Subscriber,實現了接口Observer和Subscription ,所以它可以接收事件,也可以取消訂閱。事實上,在訂閱過程中,Observer 也總會先被轉換成一個 Subscriber 再使用。
public abstract class Subscriber<T> implements Observer<T>, Subscription {
public void onStart() {
// do nothing by default
}
}
接口Function、Action系列,這些接口都有一個call()
方法,接口名中的數字代表call()
方法中的參數個數,區別在於Function系列的方法有返回值,而Action系列的方法沒有返回值。
public interface Function {
}
public interface Func1<T, R> extends Function {
R call(T t);
}
public interface Action extends Function {
}
public interface Action1<T> extends Action {
void call(T t);
}
簡單的事件流
下面的例子可以說是最簡單的使用示例,創建一個被觀察者,然後和觀察者形成訂閱關係。訂閱後,被觀察者調用3次onNext()
方法,然後結束。本篇文章就從這段簡單的代碼入手,探究RxJava
背後的原理。
Observable
.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
subscriber.onNext("消息1");
subscriber.onNext("消息2");
subscriber.onNext("消息3");
subscriber.onCompleted();
}
})
.subscribe(new Subscriber<String>() {
@Override
public void onCompleted() {
System.out.println("任務結束");
}
@Override
public void onError(Throwable e) {
System.out.println("任務出錯");
}
@Override
public void onNext(String s) {
System.out.println(s);
}
});
create()
public static <T> Observable<T> create(OnSubscribe<T> f) {
return new Observable<T>(RxJavaHooks.onCreate(f));
}
protected Observable(OnSubscribe<T> f) {
this.onSubscribe = f;
}
第2行有一個RxJavaHooks
,之後我們會看到在RxJava
中hook
頻繁地出現,它的返回值類型和入參類型都一樣。爲簡化分析,抓住重點,本篇文章不會對hook
相關部分深入探究。
第5行將對成員變量onSubscribe
賦值。
很明顯,create()
方法的作用就是將傳入的onSubscribe
賦值給成員變量onSubscribe
。
subscribe()
public final Subscription subscribe(Subscriber<? super T> subscriber) {
return Observable.subscribe(subscriber, this);
}
static <T> Subscription subscribe(Subscriber<? super T> subscriber, Observable<T> observable) {
// validate and proceed
if (subscriber == null) {
throw new IllegalArgumentException("subscriber can not be null");
}
if (observable.onSubscribe == null) {
throw new IllegalStateException("onSubscribe function can not be null.");
/*
* the subscribe function can also be overridden but generally that's not the appropriate approach
* so I won't mention that in the exception
*/
}
// new Subscriber so onStart it
subscriber.onStart();
/*
* See https://github.com/ReactiveX/RxJava/issues/216 for discussion on "Guideline 6.4: Protect calls
* to user code from within an Observer"
*/
// if not already wrapped
if (!(subscriber instanceof SafeSubscriber)) {
// assign to `observer` so we return the protected version
subscriber = new SafeSubscriber<T>(subscriber);
}
// The code below is exactly the same an unsafeSubscribe but not used because it would
// add a significant depth to already huge call stacks.
try {
// allow the hook to intercept and/or decorate
RxJavaHooks.onObservableStart(observable, observable.onSubscribe).call(subscriber);
return RxJavaHooks.onObservableReturn(subscriber);
} catch (Throwable e) {
// special handling for certain Throwable/Error/Exception types
Exceptions.throwIfFatal(e);
// in case the subscriber can't listen to exceptions anymore
if (subscriber.isUnsubscribed()) {
RxJavaHooks.onError(RxJavaHooks.onObservableError(e));
} else {
// if an unhandled error occurs executing the onSubscribe we will propagate it
try {
subscriber.onError(RxJavaHooks.onObservableError(e));
} catch (Throwable e2) {
Exceptions.throwIfFatal(e2);
// if this happens it means the onError itself failed (perhaps an invalid function implementation)
// so we are unable to propagate the error correctly and will just throw
RuntimeException r = new OnErrorFailedException("Error occurred attempting to subscribe [" + e.getMessage() + "] and then again while trying to pass to onError.", e2);
// TODO could the hook be the cause of the error in the on error handling.
RxJavaHooks.onObservableError(r);
// TODO why aren't we throwing the hook's return value.
throw r; // NOPMD
}
}
return Subscriptions.unsubscribed();
}
}
第19行調用了subscriber
的onStart()
方法,我們可以在這個方法裏做一些準備工作。
第35行調用了onSubscribe
的call()
方法,參數爲Subscriber
, 這個方法來自於它繼承的接口Action1
,而我們在call()
方法中調用了觀察者的onNext()
、onCompleted()
方法,被觀察者開始發送事件,由此實現了事件由被觀察者向觀察者的傳遞。
這裏分析的Observable
是由create()
方法創建的,我們手動在call()
方法中調用了觀察者的onNext()
、onCompleted()
方法。Observable
也可以由just()
、from()
方法創建,這些方法創建的被觀察者會自動調用觀察者的onNext()
、onCompleted()
、onError
方法,我們只需要傳入簡單的參數就可以了,但本質上和用create()
方法創建是一樣的。
subscribe()
的不同重載方法還接受Action1
、Observer
形式的參數,但它們都會被轉換爲Subscriber
,最終進入剛纔分析的subscribe()
方法中。
至此,一次簡單的事件流就清楚了:
- 賦值給成員變量
onSubscribe
- 調用
subscribe()
方法訂閱,回調onSubscribe
的call()
方法,傳入Subscriber
作爲參數,於是在call()
方法中可以調用Subscriber
的相關方法發送事件。 - 注意:只有在訂閱後纔開始發送事件。
線程調度
Observable
中有大量的操作符可以實現變換,一般用的最多的估計就是線程調度了。我們給之前的例子加上Android
中常用的線程切換:
Observable
.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
subscriber.onNext("消息1");
subscriber.onNext("消息2");
subscriber.onNext("消息3");
subscriber.onCompleted();
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<String>() {
@Override
public void onCompleted() {
System.out.println("任務結束");
}
@Override
public void onError(Throwable e) {
System.out.println("任務出錯");
}
@Override
public void onNext(String s) {
System.out.println(s);
}
});
注意:使用AndroidSchedulers.mainThread()
需要導入RxAndroid
。
我們來分析這段代碼中線程調度實現的原理,接下來涉及的源碼比較多,我們從序號1開始對源碼片段作標記。
subscribeOn()
//第1段代碼
public final Observable<T> subscribeOn(Scheduler scheduler) {
if (this instanceof ScalarSynchronousObservable) {
return ((ScalarSynchronousObservable<T>)this).scalarScheduleOn(scheduler);
}
return create(new OperatorSubscribeOn<T>(this, scheduler));
}
可以看到,調用subscribeOn()
方法後返回了一個新的Observable
。
第3行的判斷在此時爲false,我們直接看第6行,這個OperatorSubscribeOn
是新的Observable
的OnSubscribe
,跟進OperatorSubscribeOn
一探究竟。
//第2段代碼
//rx.internal.operators.OperatorSubscribeOn
public final class OperatorSubscribeOn<T> implements OnSubscribe<T> {
final Scheduler scheduler;
final Observable<T> source;
public OperatorSubscribeOn(Observable<T> source, Scheduler scheduler) {
this.scheduler = scheduler;
this.source = source;
}
@Override
public void call(final Subscriber<? super T> subscriber) {
final Worker inner = scheduler.createWorker();
subscriber.add(inner);
inner.schedule(new Action0() {
@Override
public void call() {
final Thread t = Thread.currentThread();
Subscriber<T> s = new Subscriber<T>(subscriber) {
@Override
public void onNext(T t) {
subscriber.onNext(t);
}
@Override
public void onError(Throwable e) {
try {
subscriber.onError(e);
} finally {
inner.unsubscribe();
}
}
@Override
public void onCompleted() {
try {
subscriber.onCompleted();
} finally {
inner.unsubscribe();
}
}
@Override
public void setProducer(final Producer p) {
subscriber.setProducer(new Producer() {
@Override
public void request(final long n) {
if (t == Thread.currentThread()) {
p.request(n);
} else {
inner.schedule(new Action0() {
@Override
public void call() {
p.request(n);
}
});
}
}
});
}
};
source.unsafeSubscribe(s);
}
});
}
}
在構造方法中,第9行和第10行分別保存了傳入的Observable
和Scheduler
。
OperatorSubscribeOn
作爲新的Observable
的OnSubscribe
,根據之前對subscribe()
方法的分析,它的call()
方法將在訂閱後被回調。那我們就來看一下它的call
方法:
第15行創建了Worker
類型的變量inner
,爲保持主邏輯的清晰,暫時先不管Worker
是什麼,繼續看主邏輯。
先透露一下,調用第18行的schedule()
方法後,最終將進入第20行的call()
方法。
第23行創建了一個Subscriber
,第67行的source
就是剛纔構造方法中傳入的Observable
,即上游Observable
,這裏將剛纔創建的Subscriber
作爲參數傳入了它的unsafeSubscribe()
方法,繼續跟進:
//第3段代碼
//rx.Observable
public final Subscription unsafeSubscribe(Subscriber<? super T> subscriber) {
try {
// new Subscriber so onStart it
subscriber.onStart();
// allow the hook to intercept and/or decorate
RxJavaHooks.onObservableStart(this, onSubscribe).call(subscriber);
return RxJavaHooks.onObservableReturn(subscriber);
} catch (Throwable e) {
// special handling for certain Throwable/Error/Exception types
Exceptions.throwIfFatal(e);
// if an unhandled error occurs executing the onSubscribe we will propagate it
try {
subscriber.onError(RxJavaHooks.onObservableError(e));
} catch (Throwable e2) {
Exceptions.throwIfFatal(e2);
// if this happens it means the onError itself failed (perhaps an invalid function implementation)
// so we are unable to propagate the error correctly and will just throw
RuntimeException r = new OnErrorFailedException("Error occurred attempting to subscribe [" + e.getMessage() + "] and then again while trying to pass to onError.", e2);
// TODO could the hook be the cause of the error in the on error handling.
RxJavaHooks.onObservableError(r);
// TODO why aren't we throwing the hook's return value.
throw r; // NOPMD
}
return Subscriptions.unsubscribed();
}
}
從方法名能猜出這也是一個訂閱方法,第6行更是和之前分析的subscribe()
方法進行了相同的操作,調用了上游Observable
的onSubscribe
的call()
方法。
回到第2段代碼,第26、32、41行的代碼分別調用了下游Subscriber
的對應方法。
至此,我們可以明白subscribeOn()
究竟做了什麼:
- 該方法返回了一個新的
Observable
- 新的
Observable
收到訂閱回調後,回調上游Observable
的onSubscribe
的call()
方法。 - 新的
Observable
中的OnSubscribe
的call
回調中新建的Subscriber
接收到事件後,繼續將事件傳遞給下游的Subscriber
。
那說好的子線程切換又在哪裏呢?
我們再回過頭看第2段代碼的Worker
類,它由Scheduler
創建而來。我們這裏使用的Scheduler
是Schedulers.io()
,跟進看一下:
//第4段代碼
//rx.schedulers.Schedulers 只拷貝了相關核心代碼
public final class Schedulers {
private final Scheduler ioScheduler;
public static Scheduler io() {
return RxJavaHooks.onIOScheduler(getInstance().ioScheduler);
}
private Schedulers() {
@SuppressWarnings("deprecation")
RxJavaSchedulersHook hook = RxJavaPlugins.getInstance().getSchedulersHook();
Scheduler c = hook.getComputationScheduler();
if (c != null) {
computationScheduler = c;
} else {
computationScheduler = RxJavaSchedulersHook.createComputationScheduler();
}
Scheduler io = hook.getIOScheduler();
if (io != null) {
ioScheduler = io;
} else {
ioScheduler = RxJavaSchedulersHook.createIoScheduler();
}
Scheduler nt = hook.getNewThreadScheduler();
if (nt != null) {
newThreadScheduler = nt;
} else {
newThreadScheduler = RxJavaSchedulersHook.createNewThreadScheduler();
}
}
}
第25行表明了ioScheduler
的出處:
//第5段代碼
//rx.plugins.RxJavaSchedulersHook 只拷貝了相關核心代碼
public class RxJavaSchedulersHook {
public static Scheduler createIoScheduler() {
return createIoScheduler(new RxThreadFactory("RxIoScheduler-"));
}
public static Scheduler createIoScheduler(ThreadFactory threadFactory) {
if (threadFactory == null) {
throw new NullPointerException("threadFactory == null");
}
return new CachedThreadScheduler(threadFactory);
}
}
第5行的 “RxIoScheduler-“是子線程的前綴,如果調試日誌中有輸出這個信息,那就會看到這個前綴。
第12行使用這個ThreadFactory
構建了一個CachedThreadScheduler
,繼續跟進:
//第6段代碼
//rx.internal.schedulers.CachedThreadScheduler 只拷貝了相關核心代碼
public final class CachedThreadScheduler extends Scheduler implements SchedulerLifecycle {
private static final long KEEP_ALIVE_TIME = 60;
private static final TimeUnit KEEP_ALIVE_UNIT = TimeUnit.SECONDS;
final AtomicReference<CachedWorkerPool> pool;
public CachedThreadScheduler(ThreadFactory threadFactory) {
this.threadFactory = threadFactory;
this.pool = new AtomicReference<CachedWorkerPool>(NONE);
start();
}
@Override
public void start() {
CachedWorkerPool update =
new CachedWorkerPool(threadFactory, KEEP_ALIVE_TIME, KEEP_ALIVE_UNIT);
if (!pool.compareAndSet(NONE, update)) {
update.shutdown();
}
}
@Override
public Worker createWorker() {
return new EventLoopWorker(pool.get());
}
static final class EventLoopWorker extends Scheduler.Worker implements Action0 {
private final CompositeSubscription innerSubscription = new CompositeSubscription();
private final CachedWorkerPool pool;
private final ThreadWorker threadWorker;
final AtomicBoolean once;
EventLoopWorker(CachedWorkerPool pool) {
this.pool = pool;
this.once = new AtomicBoolean();
this.threadWorker = pool.get();
}
@Override
public void unsubscribe() {
if (once.compareAndSet(false, true)) {
// unsubscribe should be idempotent, so only do this once
// Release the worker _after_ the previous action (if any) has completed
threadWorker.schedule(this);
}
innerSubscription.unsubscribe();
}
@Override
public void call() {
pool.release(threadWorker);
}
@Override
public boolean isUnsubscribed() {
return innerSubscription.isUnsubscribed();
}
@Override
public Subscription schedule(Action0 action) {
return schedule(action, 0, null);
}
@Override
public Subscription schedule(final Action0 action, long delayTime, TimeUnit unit) {
if (innerSubscription.isUnsubscribed()) {
// don't schedule, we are unsubscribed
return Subscriptions.unsubscribed();
}
ScheduledAction s = threadWorker.scheduleActual(new Action0() {
@Override
public void call() {
if (isUnsubscribed()) {
return;
}
action.call();
}
}, delayTime, unit);
innerSubscription.add(s);
s.addParent(innerSubscription);
return s;
}
}
static final class CachedWorkerPool {
private final ThreadFactory threadFactory;
private final long keepAliveTime;
CachedWorkerPool(final ThreadFactory threadFactory, long keepAliveTime, TimeUnit unit) {
this.threadFactory = threadFactory;
this.keepAliveTime = unit != null ? unit.toNanos(keepAliveTime) : 0L;
...
...
}
ThreadWorker get() {
if (allWorkers.isUnsubscribed()) {
return SHUTDOWN_THREADWORKER;
}
while (!expiringWorkerQueue.isEmpty()) {
ThreadWorker threadWorker = expiringWorkerQueue.poll();
if (threadWorker != null) {
return threadWorker;
}
}
// No cached worker found, so create a new one.
ThreadWorker w = new ThreadWorker(threadFactory);
allWorkers.add(w);
return w;
}
}
static final class ThreadWorker extends NewThreadWorker {
private long expirationTime;
ThreadWorker(ThreadFactory threadFactory) {
super(threadFactory);
this.expirationTime = 0L;
}
public long getExpirationTime() {
return expirationTime;
}
public void setExpirationTime(long expirationTime) {
this.expirationTime = expirationTime;
}
}
}
第9、10行分別給兩個成員變量賦值。
別忘了第2段代碼中的Worker
是由Scheduler
的createWorker()
方法創建的,所以看一下第25行的createWorker()
方法,pool.get()
獲取到的是pool
指定的泛型CachedWorkerPool
,將它傳入EventLoopWorker
的構造方法,在第38行調用了get()
方法跳轉到第99行,之後在第111行用剛纔的threadFactory
構造了ThreadWorker
,於是在第121行進入父類NewThreadWorker
的構造方法,該父類如下:
//第7段代碼
//rx.internal.schedulers.NewThreadWorker 只拷貝了相關核心代碼
public class NewThreadWorker extends Scheduler.Worker implements Subscription {
private final ScheduledExecutorService executor;
public NewThreadWorker(ThreadFactory threadFactory) {
ScheduledExecutorService exec = Executors.newScheduledThreadPool(1, threadFactory);
// Java 7+: cancelled future tasks can be removed from the executor thus avoiding memory leak
boolean cancelSupported = tryEnableCancelPolicy(exec);
if (!cancelSupported && exec instanceof ScheduledThreadPoolExecutor) {
registerExecutor((ScheduledThreadPoolExecutor)exec);
}
executor = exec;
}
public ScheduledAction scheduleActual(final Action0 action, long delayTime, TimeUnit unit) {
Action0 decoratedAction = RxJavaHooks.onScheduledAction(action);
ScheduledAction run = new ScheduledAction(decoratedAction);
Future<?> f;
if (delayTime <= 0) {
f = executor.submit(run);
} else {
f = executor.schedule(run, delayTime, unit);
}
run.add(f);
return run;
}
}
第7行使用Executors
創建了一個線程池,傳入了兩個參數:核心線程數1、之前分析的帶有前綴“RxIoScheduler-“的ThreadFactory
。最大線程數爲Integer.MAX_VALUE
,非核心線程保留10ms。
第2段代碼的Worker
會調用schedule
方法,所以再回到第6段代碼的68行,之後在第74行調用了ThreadWorker
的scheduleActual()
方法,於是跳轉到第7段代碼的第16行。第17行對action
進行了包裝,第18行將包裝後的action
轉換成ScheduledAction
對象,這是一個Runnable
對象,所以第21行可以將它作爲executor.submit()
方法的參數,這個executor
就是剛纔創建的線程池。
之後線程池將會新開線程,並調用ScheduledAction
的run()
方法,繼續跟進:
//第8段代碼
//rx.internal.schedulers.ScheduledAction 只拷貝了相關核心代碼
public final class ScheduledAction extends AtomicReference<Thread> implements Runnable, Subscription {
final SubscriptionList cancel;
final Action0 action;
public ScheduledAction(Action0 action) {
this.action = action;
this.cancel = new SubscriptionList();
}
@Override
public void run() {
try {
lazySet(Thread.currentThread());
action.call();
} catch (OnErrorNotImplementedException e) {
signalError(new IllegalStateException("Exception thrown on Scheduler.Worker thread. Add `onError` handling.", e));
} catch (Throwable e) {
signalError(new IllegalStateException("Fatal Exception thrown on Scheduler.Worker thread.", e));
} finally {
unsubscribe();
}
}
}
第16行的action
就是剛纔包裝後的decoratedAction
,所以跳轉到第6段代碼的第76行,之後在第80行又回調call()
方法,跳轉到第2段代碼的第20行,接着就是之前分析過的 “回調上游Observable的onSubscribe的call()方法”。
至此,第2段代碼就已經打通了,子線程也已經開始運行。
我們對subscribeOn()
的總結再加以完善:
- 該方法返回了一個新的
Observable
- 新的
Observable
收到訂閱回調後, 創建了一個核心線程數爲1,最大線程數爲Integer.MAX_VALUE
的線程池,新線程名的前綴爲 “RxIoScheduler-“,之後的代碼將運行在新線程中,直到遇到線程切換。 - 通過層層回調,最終回調了上游
Observable
的onSubscribe
的call()
方法。 - 新的
Observable
中的OnSubscribe
的call
回調中新建的Subscriber
接收到事件後,繼續將事件傳遞給下游的Subscriber
。 - 該方法改變的是上游回調
call()
方法執行時所處的線程,當使用多個subscribeOn()
時,只有第一個subscribeOn()
決定事件發送時的線程。
observeOn()
現在我們看一下observeOn(AndroidSchedulers.mainThread())
這行代碼實現的原理:
//第9段代碼
public final Observable<T> observeOn(Scheduler scheduler) {
return observeOn(scheduler, RxRingBuffer.SIZE);
}
public final Observable<T> observeOn(Scheduler scheduler, int bufferSize) {
return observeOn(scheduler, false, bufferSize);
}
public final Observable<T> observeOn(Scheduler scheduler, boolean delayError, int bufferSize) {
if (this instanceof ScalarSynchronousObservable) {
return ((ScalarSynchronousObservable<T>)this).scalarScheduleOn(scheduler);
}
return lift(new OperatorObserveOn<T>(scheduler, delayError, bufferSize));
}
public final <R> Observable<R> lift(final Operator<? extends R, ? super T> operator) {
return create(new OnSubscribeLift<T, R>(onSubscribe, operator));
}
經過兩個方法的調用,在第14行出現了新的對象OperatorObserveOn
,先不管它,繼續看主邏輯。
第18行又是我們熟悉的create()
方法,不用多說,它的參數是個OnSubscribe
接口對象,跟進OnSubscribeLift
:
//第10段代碼
public final class OnSubscribeLift<T, R> implements OnSubscribe<R> {
final OnSubscribe<T> parent;
final Operator<? extends R, ? super T> operator;
public OnSubscribeLift(OnSubscribe<T> parent, Operator<? extends R, ? super T> operator) {
this.parent = parent;
this.operator = operator;
}
@Override
public void call(Subscriber<? super R> o) {
try {
Subscriber<? super T> st = RxJavaHooks.onObservableLift(operator).call(o);
try {
st.onStart();
parent.call(st);
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
st.onError(e);
}
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
o.onError(e);
}
}
}
這個類代碼不多,比較簡單。第16行新建了一個Subscriber
對象,緊接着又是熟悉的操作:調用這個新Subscriber
對象的onStart()
方法、回調上游OnSubscribe
的call()
方法。
很明顯,這裏收到訂閱回調後沒有發生線程切換,也沒有其他多餘的操作。
那這個新的Subscriber
對象接收到事件後,又發生了什麼呢?
根據第16行,我們要看第9段代碼第14行OperatorObserveOn
的call()
方法來了解這個新的Subscriber
對象了:
//第11段代碼
//rx.internal.operators.OperatorObserveOn 只拷貝了相關核心代碼
public final class OperatorObserveOn<T> implements Operator<T, T> {
public OperatorObserveOn(Scheduler scheduler, boolean delayError, int bufferSize) {
this.scheduler = scheduler;
this.delayError = delayError;
this.bufferSize = (bufferSize > 0) ? bufferSize : RxRingBuffer.SIZE;
}
@Override
public Subscriber<? super T> call(Subscriber<? super T> child) {
if (scheduler instanceof ImmediateScheduler) {
// avoid overhead, execute directly
return child;
} else if (scheduler instanceof TrampolineScheduler) {
// avoid overhead, execute directly
return child;
} else {
ObserveOnSubscriber<T> parent = new ObserveOnSubscriber<T>(scheduler, child, delayError, bufferSize);
parent.init();
return parent;
}
}
static final class ObserveOnSubscriber<T> extends Subscriber<T> implements Action0 {
public ObserveOnSubscriber(Scheduler scheduler, Subscriber<? super T> child, boolean delayError, int bufferSize) {
this.child = child;
this.recursiveScheduler = scheduler.createWorker();
this.delayError = delayError;
...
...
}
@Override
public void onNext(final T t) {
if (isUnsubscribed() || finished) {
return;
}
if (!queue.offer(NotificationLite.next(t))) {
onError(new MissingBackpressureException());
return;
}
schedule();
}
@Override
public void onCompleted() {
if (isUnsubscribed() || finished) {
return;
}
finished = true;
schedule();
}
@Override
public void onError(final Throwable e) {
if (isUnsubscribed() || finished) {
RxJavaHooks.onError(e);
return;
}
error = e;
finished = true;
schedule();
}
protected void schedule() {
if (counter.getAndIncrement() == 0) {
recursiveScheduler.schedule(this);
}
}
}
}
進入第12行的call()
方法,因爲我們使用的是AndroidSchedulers.mainThread()
,所以就直接到了第20行。這裏將ObserveOnSubscriber
作爲Subscriber
返回,所以再看這個對象的onNext()
等方法就知道如何處理事件了。
第40行將當前接收到的事件保存進了隊列queue
,先記住這點,後面就會用到了。
第44、53、64行都調用了schedule()
這個方法。注意:onCompleted()
和onError
方法中都將標誌位finished
設爲了true
。
第69行調用了recursiveScheduler
的schedule()
方法,recursiveScheduler
是在第20行跳到29行賦值的,我們需要找到AndroidSchedulers.mainThread()
的createWorker()
方法,先找到AndroidSchedulers.mainThread()
:
//第12段代碼
//rx.android.schedulers.AndroidSchedulers 只拷貝了相關核心代碼
public final class AndroidSchedulers {
private final Scheduler mainThreadScheduler;
private AndroidSchedulers() {
RxAndroidSchedulersHook hook = RxAndroidPlugins.getInstance().getSchedulersHook();
Scheduler main = hook.getMainThreadScheduler();
if (main != null) {
mainThreadScheduler = main;
} else {
mainThreadScheduler = new LooperScheduler(Looper.getMainLooper());
}
}
}
第13行用主線程的Looper
構建了LooperScheduler
,繼續跟進:
//第13段代碼
//rx.android.schedulers.Scheduler
class LooperScheduler extends Scheduler {
private final Handler handler;
LooperScheduler(Looper looper) {
handler = new Handler(looper);
}
@Override
public Worker createWorker() {
return new HandlerWorker(handler);
}
static class HandlerWorker extends Worker {
@Override
public Subscription schedule(final Action0 action) {
return schedule(action, 0, TimeUnit.MILLISECONDS);
}
@Override
public Subscription schedule(Action0 action, long delayTime, TimeUnit unit) {
if (unsubscribed) {
return Subscriptions.unsubscribed();
}
action = hook.onSchedule(action);
ScheduledAction scheduledAction = new ScheduledAction(action, handler);
Message message = Message.obtain(handler, scheduledAction);
message.obj = this; // Used as token for unsubscription operation.
handler.sendMessageDelayed(message, unit.toMillis(delayTime));
if (unsubscribed) {
handler.removeCallbacks(scheduledAction);
return Subscriptions.unsubscribed();
}
return scheduledAction;
}
}
static final class ScheduledAction implements Runnable, Subscription {
ScheduledAction(Action0 action, Handler handler) {
this.action = action;
this.handler = handler;
}
@Override
public void run() {
try {
action.call();
} catch (Throwable e) {
...
}
}
}
}
第12行又用主線程的Looper
構建了HandlerWorker
,所以只要看HandlerWorker
的schedule()
方法就行了。
第35行向主線程的消息隊列發送了一條消息,這條消息將被主線程的Looper
取出,到時候第30行scheduledAction
的回調run()
方法就會在主線程執行了,這就實現了切換回主線程的目的。
再看第53行,run()
方法裏又回調了action
的call()
方法,即第11段代碼第26行類ObserveOnSubscriber
所實現的方法,如下:
@Override
public void call() {
long missed = 1L;
long currentEmission = emitted;
final Queue<Object> q = this.queue;
final Subscriber<? super T> localChild = this.child;
for (;;) {
long requestAmount = requested.get();
while (requestAmount != currentEmission) {
boolean done = finished;
Object v = q.poll();
boolean empty = v == null;
if (checkTerminated(done, empty, localChild, q)) {
return;
}
if (empty) {
break;
}
localChild.onNext(NotificationLite.<T>getValue(v));
currentEmission++;
if (currentEmission == limit) {
requestAmount = BackpressureUtils.produced(requested, currentEmission);
request(currentEmission);
currentEmission = 0L;
}
}
if (requestAmount == currentEmission) {
if (checkTerminated(finished, q.isEmpty(), localChild, q)) {
return;
}
}
emitted = currentEmission;
missed = counter.addAndGet(-missed);
if (missed == 0L) {
break;
}
}
}
第6行的localChild
就是下游Subscriber
,這從第11代碼中不難發現。
第12行取出了之前保存在隊列queue
中的事件,第23行調用了下游Subscriber
的onNext()
方法,事件繼續向下傳遞,而這一切都發生在主線程中。
至此,對observeOn()
方法可以有如下總結:
- 該方法返回了一個新的
Observable
- 新的
Observable
收到訂閱回調後,回調了上游Observable
的onSubscribe
的call()
方法。 - 新的
Observable
中的OnSubscribe
的call
回調中新建的Subscriber
接收到事件後,將事件包裝後發送到主線程的消息隊列。 - 在主線程中,事件繼續向下遊
Subscriber
傳遞。 - 該方法改變的是下游訂閱者方法執行時所處的線程,可以通過多次調用
observeOn()
方法,實現下游訂閱者在多個線程間切換執行。
線程調度總結
以上對兩種線程調度操作符都做了詳細的分析和總結,切換線程時一個利用線程池,一個利用主線程Looper
消息機制。
再配合下面這幅流程圖食用,消化更佳~
這幅圖來自於扔物線的給 Android 開發者的 RxJava 詳解,因爲這幅圖總結地很好,和本文分析的結論也是完全一致,所以就直接拿來用了。
相信理解完本文內容,大家對RxJava 1.x
應該有了較好的認識,當然它的其他實現原理也很值得我們再深入研究。