文章目录
在分析 RxJava 源码之前,先说一下需要关注的两个方法:onSubscribe()
和 onSuccess()
。
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);
}
// 通过 debug 会发现它只会返回我们传递的参数 source,也就是 SingleJust
return source;
}
------------------------------------------------------------------------------------------------
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.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。
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,比较灵活。
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);
}
}
}
}
Schedulers 线程切换
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()
指定的线程中运行。
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()
切换线程是在接收到上游事件的时候才开始切换线程,所以它只会影响的下游的操作符线程。
流程图如下: