文章目錄
在RxJava源碼分析之前,先說一下需要關注的兩個方法:onSubscribe()
和 onSuccess()
。
1 Single.just()
我們會從RxJava使用的用例來切入源碼的分析。首先看一下最基本最簡單的一個RxJava使用例子 Single
:
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) {
}
});
我們首先從 subscribe()
進入源碼分析:
Single.java
@SchedulerSupport(SchedulerSupport.NONE)
@Override
public final void subscribe(SingleObserver<? super T> observer) {
ObjectHelper.requireNonNull(observer, "subscriber is null");
observer = RxJavaPlugins.onSubscribe(this, observer);
ObjectHelper.requireNonNull(observer, "The RxJavaPlugins.onSubscribe hook returned a null SingleObserver. Please check the handler provided to RxJavaPlugins.setOnSingleSubscribe for invalid null returns. Further reading: https://github.com/ReactiveX/RxJava/wiki/Plugins");
try {
// 上面都是判空沒什麼好說的,整個方法最主要的就是這個方法
subscribeActual(observer);
} catch (NullPointerException ex) {
throw ex;
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
NullPointerException npe = new NullPointerException("subscribeActual failed");
npe.initCause(ex);
throw npe;
}
}
protected abstract void subscribeActual(@NonNull SingleObserver<? super T> observer);
上面分析到最主要的一個方法是 subscribeActual()
,但它是一個抽象方法沒法繼續分析,所以我們要退回剛纔的例子,從操作符 just()
分析:
Signle.java
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@NonNull
public static <T> Single<T> just(final T item) {
// 判空沒什麼好說的
ObjectHelper.requireNonNull(item, "value is null");
// RxJavaPlugins.onAssembly()其實是一個鉤子,這個方法其實會返回的SingleJust類
return RxJavaPlugins.onAssembly(new SingleJust<T>(item));
}
@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; // 通過debug會發現它只會返回我們傳遞的參數source,也就是SingleJust
}
------------------------------------------------------------------------------------------------
SingleJust.java
public final class SingleJust<T> extends Single<T> {
final T value;
public SingleJust(T value) {
this.value = value;
}
// SingleJust是Single的子類,而剛纔的分析Single.subscribe()內部是調用的subscribeActual()抽象方法
// 所以這裏就是具體的實現
@Override
protected void subscribeActual(SingleObserver<? super T> observer) {
// 參數SingleObserver是我們調用Single.subcribe(SingleObserver)傳遞進來的參數,最終就是調用回去
// just()是瞬時發送的,所以它沒有調用onError()
observer.onSubscribe(Disposables.disposed());
observer.onSuccess(value);
}
}
public final class Disposables {
....
@NonNull
public static Disposable disposed() {
return EmptyDisposable.INSTANCE;
}
}
public enum EmptyDisposable implements QueueDisposable<Object> {
/**
* Since EmptyDisposable implements QueueDisposable and is empty,
* don't use it in tests and then signal onNext with it;
* use Disposables.empty() instead.
*/
INSTANCE,
/**
* An empty disposable that returns false for isDisposed.
*/
NEVER
;
// Disposable是可以切斷上游Observable發送事件到下游
// 這裏的Disposable.dispose()沒有做任何事情,因爲just()一接收到就直接發送了,所以不提供也不需要切斷
@Override
public void dispose() {
// no-op
}
}
通過上面的分析,也就解析清楚這個簡單例子做的事情了。使用RxJava時,當我們調用 subscribe()
時,事件才正式開始發送。而 just()
操作符會創建一個新的 Observable
,接收到數據就直接發送了。
流程圖如下:
2 Single.map()
先寫一個簡單的例子,同樣還是Single:
Single.just(1).map(new Function<Integer, String>() {
@Override
public String apply(Integer integer) throws Exception {
return String.valueOf(integer);
}
}).subscribe(new SingleObserver<String>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onSuccess(String s) {
}
@Override
public void onError(Throwable e) {
}
});
操作符 just()
上面已經分析了,我們進去分析下操作符 map()
,看它是怎麼實現的數據類型轉換:
Single.java
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public final <R> Single<R> map(Function<? super T, ? extends R> mapper) {
ObjectHelper.requireNonNull(mapper, "mapper is null");
return RxJavaPlugins.onAssembly(new SingleMap<T, R>(this, mapper));
}
------------------------------------------------------------------------------------------------
SingleMap.java
public final class SingleMap<T, R> extends Single<R> {
final SingleSource<? extends T> source;
final Function<? super T, ? extends R> mapper;
public SingleMap(SingleSource<? extends T> source, Function<? super T, ? extends R> mapper) {
this.source = source;
this.mapper = mapper;
}
// 同樣的也是在調用了Single.subscribe()的時候纔會開始發送事件
// 這裏的source通過上面發現它是一個this,其實就是上游Observable,也就是Single.just()返回的Single子類SingleJust
// 首先會將事件發送給上游Observable,傳遞給它一個MapSingleObserver
@Override
protected void subscribeActual(final SingleObserver<? super R> t) {
source.subscribe(new MapSingleObserver<T, R>(t, mapper));
}
static final class MapSingleObserver<T, R> implements SingleObserver<T> {
final SingleObserver<? super R> t;
final Function<? super T, ? extends R> mapper;
MapSingleObserver(SingleObserver<? super R> t, Function<? super T, ? extends R> mapper) {
this.t = t;
this.mapper = mapper;
}
// 在SingleJust調用subscribeActual()的時候,會調用這個Observer的onSubscribe()
// 成員t是Single.subscribe(Observer)傳遞過來的,這裏沒做任何處理就直接發送
// 參數d也是在SingleJust傳過來的,也是不做任何切斷處理
@Override
public void onSubscribe(Disposable d) {
t.onSubscribe(d);
}
// 在SingleJust調用subscribeActual()的時候,會調用這個Observer的onSuccess()
// 這裏的value參數是上游SingleJust接收的,在這裏通過mapper做數據類型轉換
// mapper是我們創建的Function
@Override
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);
}
@Override
public void onError(Throwable e) {
t.onError(e);
}
}
}
流程圖如下:
流程圖是從左往右看的,在 subscribe()
的時候,從左邊開始往上,然後到右邊往下的箭頭傳遞事件。
當調用 subscribe()
的時候,Observable和Observer才訂閱開始發送事件,事件會先走到 Single.map(mapper)
,然後提供一個Observer給源頭Observable,然後纔將事件往下傳遞到Observer。
3 AtomicReference
先上例子:
Observable.interval(0, 1, TimeUnit.SECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribe();
上面例子是一個定時器,每秒發送一次,內部是怎麼實現的?但這裏先不講解線程切換Schedulers相關的內容,而是要講解 AtomicReference<>
這個類,方便在看其他操作符源碼的時候知道這個東西是什麼。
Observable.java
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.COMPUTATION)
public static Observable<Long> interval(long initialDelay, long period, TimeUnit unit) {
// interval()操作符已經幫我們提供了Schedulers調度器
return interval(initialDelay, period, unit, Schedulers.computation());
}
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.CUSTOM)
public static Observable<Long> interval(long initialDelay, long period, TimeUnit unit, Scheduler scheduler) {
ObjectHelper.requireNonNull(unit, "unit is null");
ObjectHelper.requireNonNull(scheduler, "scheduler is null");
return RxJavaPlugins.onAssembly(new ObservableInterval(Math.max(0L, initialDelay), Math.max(0L, period), unit, scheduler));
}
------------------------------------------------------------------------------------------------
ObservableInternal.java
public final class ObservableInterval extends Observable<Long> {
final Scheduler scheduler;
final long initialDelay;
final long period;
final TimeUnit unit;
public ObservableInterval(long initialDelay, long period, TimeUnit unit, Scheduler scheduler) {
this.initialDelay = initialDelay;
this.period = period;
this.unit = unit;
this.scheduler = scheduler;
}
@Override
public void subscribeActual(Observer<? super Long> observer) {
IntervalObserver is = new IntervalObserver(observer);
// 提供給下游的是IntervalObserver
// 而下面代碼is.setResource(d)將IntervalObserver這個代理指向了sch.schedulePeriodicallyDirect()這個Disposable
// 所以下游調用Disposable.dispose()是切斷的sch.schedulePeriodicallyDirect()這個Disposable
observer.onSubscribe(is);
Scheduler sch = scheduler;
if (sch instanceof TrampolineScheduler) {
Worker worker = sch.createWorker();
is.setResource(worker);
worker.schedulePeriodically(is, initialDelay, period, unit);
} else {
// 一般都會走到這段代碼
Disposable d = sch.schedulePeriodicallyDirect(is, initialDelay, period, unit);
is.setResource(d);
}
}
// 這個Observable即是一個Disposable又是一個Runnable
// AtomicReference<Disposable>是什麼東西?怎麼繼承了它又實現了Disposable?
// 其實它類似於一個代理,它的具體實現指向實際的那個Disposable引用,這個Disposable引用可以是自己,也可以是其他Disposable
// AtomicReference<Disposable>指向的是上游
static final class IntervalObserver
extends AtomicReference<Disposable>
implements Disposable, Runnable {
private static final long serialVersionUID = 346773832286157679L;
final Observer<? super Long> downstream;
long count;
IntervalObserver(Observer<? super Long> downstream) {
this.downstream = downstream;
}
// 因爲在setResource(Disposable d)時這個AutomicReference指向的是sch.schedulePeriodicallyDirect()提供的Disposable
// 所以調用dispose()實際是停止切斷了指向的那個Disposable,將停止事件再往下游發送
@Override
public void dispose() {
DisposableHelper.dispose(this);
}
@Override
public boolean isDisposed() {
return get() == DisposableHelper.DISPOSED;
}
// IntervalObserver是一個Runnable
// sch.schedulePeriodicallyDirect(is, initialDelay, period, unit)內部也是一個Executors線程池處理,會調用run()
@Override
public void run() {
if (get() != DisposableHelper.DISPOSED) {
downstream.onNext(count++);
}
}
// 通過這句代碼能夠知道,這裏的Disposable是通過sch.schedulePeriodicallyDirect(is, initialDelay, period, unit)獲得
// AtomicReference<Disposable>指向的是傳參過來的Disposable
public void setResource(Disposable d) {
DisposableHelper.setOnce(this, d);
}
}
}
根據上面代碼分析,其實 AtomicReference<>
就是一個Disposable的代理,但是它可以指向自己,也可以指向其他Disposable,比較靈活。
4 delay()
Single.just().delay().subscribe()
Single.java
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.CUSTOM)
public final Single<T> delay(final long time, final TimeUnit unit, final Scheduler scheduler, boolean delayError) {
ObjectHelper.requireNonNull(unit, "unit is null");
ObjectHelper.requireNonNull(scheduler, "scheduler is null");
return RxJavaPlugins.onAssembly(new SingleDelay<T>(this, time, unit, scheduler, delayError));
}
------------------------------------------------------------------------------------------------
SingleDelay.java
public final class SingleDelay<T> extends Single<T> {
final SingleSource<? extends T> source;
final long time;
final TimeUnit unit;
final Scheduler scheduler;
final boolean delayError;
public SingleDelay(SingleSource<? extends T> source, long time, TimeUnit unit, Scheduler scheduler, boolean delayError) {
this.source = source;
this.time = time;
this.unit = unit;
this.scheduler = scheduler;
this.delayError = delayError;
}
@Override
protected void subscribeActual(final SingleObserver<? super T> observer) {
final SequentialDisposable sd = new SequentialDisposable();
observer.onSubscribe(sd);
source.subscribe(new Delay(sd, observer));
}
// SequentialDisposable也是AtomicReference,所以也是一個代理
final class Delay implements SingleObserver<T> {
private final SequentialDisposable sd;
final SingleObserver<? super T> downstream;
Delay(SequentialDisposable sd, SingleObserver<? super T> observer) {
this.sd = sd;
this.downstream = observer;
}
// 這裏是一個比較有意思的地方
// 當事件未發送到下游前,這裏sd指向的是上游,也就是會切斷上游
@Override
public void onSubscribe(Disposable d) {
sd.replace(d);
}
// 當事件發送過來後,sd重新指向了scheduler.scheduleDirect()的Disposable
// 會切斷scheduler.scheduleDirect()的事件發送
// 事件發送後,就和你上游沒有關係了
@Override
public void onSuccess(final T value) {
sd.replace(scheduler.scheduleDirect(new OnSuccess(value), time, unit));
}
@Override
public void onError(final Throwable e) {
sd.replace(scheduler.scheduleDirect(new OnError(e), delayError ? time : 0, unit));
}
final class OnSuccess implements Runnable {
private final T value;
OnSuccess(T value) {
this.value = value;
}
@Override
public void run() {
downstream.onSuccess(value);
}
}
final class OnError implements Runnable {
private final Throwable e;
OnError(Throwable e) {
this.e = e;
}
@Override
public void run() {
downstream.onError(e);
}
}
}
}
6 Schedulers線程切換
6.1 subscribeOn(schedulers)
RxJava能夠一句代碼就實現線程的切換,到底怎麼實現的?這裏用 Single.subscribeOn()
來看具體的源碼。
Single.just().subscribeOn(Schedulers.newThread()).subscribe()
public final class SingleSubscribeOn<T> extends Single<T> {
final SingleSource<? extends T> source;
final Scheduler scheduler;
public SingleSubscribeOn(SingleSource<? extends T> source, Scheduler scheduler) {
this.source = source;
this.scheduler = scheduler;
}
@Override
protected void subscribeActual(final SingleObserver<? super T> observer) {
final SubscribeOnObserver<T> parent = new SubscribeOnObserver<T>(observer, source);
observer.onSubscribe(parent);
// scheduler是調用subscribeOn()傳遞的Schedulers
// 這裏傳入的是Schedulers.newThread()
// subscribeOn()在發生訂閱的時候就已經開始切換了線程
Disposable f = scheduler.scheduleDirect(parent);
parent.task.replace(f);
}
static final class SubscribeOnObserver<T>
extends AtomicReference<Disposable>
implements SingleObserver<T>, Disposable, Runnable {
private static final long serialVersionUID = 7000911171163930287L;
final SingleObserver<? super T> downstream;
final SequentialDisposable task;
final SingleSource<? extends T> source;
SubscribeOnObserver(SingleObserver<? super T> actual, SingleSource<? extends T> source) {
this.downstream = actual;
this.source = source;
this.task = new SequentialDisposable();
}
@Override
public void onSubscribe(Disposable d) {
DisposableHelper.setOnce(this, d);
}
@Override
public void onSuccess(T value) {
downstream.onSuccess(value);
}
@Override
public void onError(Throwable e) {
downstream.onError(e);
}
@Override
public void dispose() {
DisposableHelper.dispose(this);
task.dispose();
}
@Override
public boolean isDisposed() {
return DisposableHelper.isDisposed(get());
}
// scheduler.scheduleDirect()使用Worker切換了線程
// Worker內部最終也是使用線程池實現,這裏切了線程後,就丟給上游
@Override
public void run() {
source.subscribe(this);
}
}
}
------------------------------------------------------------------------------------------------
Schedulers.java
@NonNull
public Disposable scheduleDirect(@NonNull Runnable run, long delay, @NonNull TimeUnit unit) {
// 現在使用的是Schedulers.newThread(),這個Worker是NewThreadWorker
final Worker w = createWorker();
// 一個鉤子,其實decoratedRun還是傳參的那個run
final Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
// 它其實就是一個封裝類,主要的還是傳入的NewThreadWorker工作
DisposeTask task = new DisposeTask(decoratedRun, w);
// task是一個Runnable,當NewThreadWorker調用schedule()時,就將task這個Runnable丟到線程池去
// 而task的run()其實調用的是decorateRun.run()
w.schedule(task, delay, unit);
return task;
}
static final class DisposeTask implements Disposable, Runnable, SchedulerRunnableIntrospection {
...
@Override
public void run() {
runner = Thread.currentThread();
try {
decoratedRun.run();
} finally {
dispose();
runner = null;
}
}
@Override
public void dispose() {
if (runner == Thread.currentThread() && w instanceof NewThreadWorker) {
((NewThreadWorker)w).shutdown();
} else {
w.dispose();
}
}
}
// 可以發現,RxJava切換線程最終還是使用的線程池Executor
public class NewThreadWorker extends Scheduler.Worker implements Disposable {
private final ScheduledExecutorService executor;
....
@NonNull
@Override
public Disposable schedule(@NonNull final Runnable run) {
return schedule(run, 0, null);
}
@NonNull
@Override
public Disposable schedule(@NonNull final Runnable action, long delayTime, @NonNull TimeUnit unit) {
if (disposed) {
return EmptyDisposable.INSTANCE;
}
return scheduleActual(action, delayTime, unit, null);
}
@NonNull
public ScheduledRunnable scheduleActual(final Runnable run, long delayTime, @NonNull TimeUnit unit, @Nullable DisposableContainer parent) {
Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
ScheduledRunnable sr = new ScheduledRunnable(decoratedRun, parent);
if (parent != null) {
if (!parent.add(sr)) {
return sr;
}
}
Future<?> f;
try {
if (delayTime <= 0) {
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;
}
...
// Disposable.dispose()其實就是暫停線程
@Override
public void dispose() {
if (!disposed) {
disposed = true;
executor.shutdownNow();
}
}
}
流程圖如下:
從左往右看,調用 subscribeOn()
的時候做了線程切換,這裏用線程變成黃色來表示,即當 subscribe()
調用訂閱時,在 subscribeOn()
進行了線程切換,然後往後都是在切換的線程中發送事件到下游。
如果是 Single.just().subscribeOn(Schedulers.newThread()).map().subscribe()
,流程圖如下:
可以看到,在 map()
操作符的時候線程還是在主線程,經過 subscribeOn()
後,發送事件都在切換的線程中執行了。
從這張圖也可以解釋一個問題,爲什麼調用多次 subscribeOn()
切換線程或者在訂閱前調用只切換一次線程。按左邊的圖,代碼順序比如 Single.just().subscribeOn().map().subscribe()
或者 Single.just().map().subscribeOn().subscribe()
,最終右邊我們實際發送到下游都是在 subscribeOn()
指定的線程中運行。而 Single.just().subscribeOn().subscribeOn().map().subscrib()
總是會在第一個 subscribeOn()
指定的線程中運行。
6.2 observeOn(schedulers)
public final class SingleObserveOn<T> extends Single<T> {
final SingleSource<T> source;
final Scheduler scheduler;
public SingleObserveOn(SingleSource<T> source, Scheduler scheduler) {
this.source = source;
this.scheduler = scheduler;
}
@Override
protected void subscribeActual(final SingleObserver<? super T> observer) {
// 在接收到消息的時候交給了ObserveOnSingleObserver
source.subscribe(new ObserveOnSingleObserver<T>(observer, scheduler));
}
static final class ObserveOnSingleObserver<T> extends AtomicReference<Disposable>
implements SingleObserver<T>, Disposable, Runnable {
private static final long serialVersionUID = 3528003840217436037L;
final SingleObserver<? super T> downstream;
final Scheduler scheduler;
T value;
Throwable error;
ObserveOnSingleObserver(SingleObserver<? super T> actual, Scheduler scheduler) {
this.downstream = actual;
this.scheduler = scheduler;
}
@Override
public void onSubscribe(Disposable d) {
// 在跟下游訂閱的時候還沒有切線程
if (DisposableHelper.setOnce(this, d)) {
downstream.onSubscribe(this);
}
}
@Override
public void onSuccess(T value) {
// 在接收到事件發送給下游的時候纔開始切換線程,然後在run()將事件往下傳給下游
// 所以ObserveOn()切換線程影響的是下游
this.value = value;
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) {
downstream.onError(ex);
} else {
downstream.onSuccess(value);
}
}
@Override
public void dispose() {
DisposableHelper.dispose(this);
}
@Override
public boolean isDisposed() {
return DisposableHelper.isDisposed(get());
}
}
}
根據上面的分析,observeOn()
切換線程是在接收到上游事件的時候纔開始切換線程,所以它只會影響的下游的操作符線程。
流程圖如下: