在RxJava源码分析之前,先说一下需要关注的两个方法:onSubscribe()
和 onSuccess()
。
我们会从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
,接收到数据就直接发送了。
流程图如下:
先写一个简单的例子,同样还是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。
先上例子:
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
// AtomicReference指向的是上游
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
public void setResource(Disposable d) {
DisposableHelper.setOnce(this, d);
}
}
}
根据上面代码分析,其实 AtomicReference<>
就是一个Disposable的代理,但是它可以指向自己,也可以指向其他Disposable,比较灵活。
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);
}
}
}
}
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()
指定的线程中运行。
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()
切换线程是在接收到上游事件的时候才开始切换线程,所以它只会影响的下游的操作符线程。
流程图如下: