目前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 onSubscribe;
public interface OnSubscribe<T> extends Action1<Subscriber super T>> {
// cover for generics insanity
}
}
观察者-接口Observer,事件的消费者。
public interface Observer {
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() {
@Override
public void call(Subscriber super String> subscriber) {
subscriber.onNext("消息1");
subscriber.onNext("消息2");
subscriber.onNext("消息3");
subscriber.onCompleted();
}
})
.subscribe(new Subscriber() {
@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);
}
});
public static Observable create(OnSubscribe f) {
return new Observable(RxJavaHooks.onCreate(f));
}
protected Observable(OnSubscribe f) {
this.onSubscribe = f;
}
第2行有一个RxJavaHooks
,之后我们会看到在RxJava
中hook
频繁地出现,它的返回值类型和入参类型都一样。为简化分析,抓住重点,本篇文章不会对hook
相关部分深入探究。
第5行将对成员变量onSubscribe
赋值。
很明显,create()
方法的作用就是将传入的onSubscribe
赋值给成员变量onSubscribe
。
public final Subscription subscribe(Subscriber super T> subscriber) {
return Observable.subscribe(subscriber, this);
}
static Subscription subscribe(Subscriber super T> subscriber, Observable 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(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() {
@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() {
@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开始对源码片段作标记。
//第1段代码
public final Observable subscribeOn(Scheduler scheduler) {
if (this instanceof ScalarSynchronousObservable) {
return ((ScalarSynchronousObservable)this).scalarScheduleOn(scheduler);
}
return create(new OperatorSubscribeOn(this, scheduler));
}
可以看到,调用subscribeOn()
方法后返回了一个新的Observable
。
第3行的判断在此时为false,我们直接看第6行,这个OperatorSubscribeOn
是新的Observable
的OnSubscribe
,跟进OperatorSubscribeOn
一探究竟。
//第2段代码
//rx.internal.operators.OperatorSubscribeOn
public final class OperatorSubscribeOn implements OnSubscribe {
final Scheduler scheduler;
final Observable source;
public OperatorSubscribeOn(Observable 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 s = new Subscriber(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 pool;
public CachedThreadScheduler(ThreadFactory threadFactory) {
this.threadFactory = threadFactory;
this.pool = new AtomicReference(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(AndroidSchedulers.mainThread())
这行代码实现的原理:
//第9段代码
public final Observable observeOn(Scheduler scheduler) {
return observeOn(scheduler, RxRingBuffer.SIZE);
}
public final Observable observeOn(Scheduler scheduler, int bufferSize) {
return observeOn(scheduler, false, bufferSize);
}
public final Observable observeOn(Scheduler scheduler, boolean delayError, int bufferSize) {
if (this instanceof ScalarSynchronousObservable) {
return ((ScalarSynchronousObservable)this).scalarScheduleOn(scheduler);
}
return lift(new OperatorObserveOn(scheduler, delayError, bufferSize));
}
public final Observable lift(final Operator extends R, ? super T> operator) {
return create(new OnSubscribeLift(onSubscribe, operator));
}
经过两个方法的调用,在第14行出现了新的对象OperatorObserveOn
,先不管它,继续看主逻辑。
第18行又是我们熟悉的create()
方法,不用多说,它的参数是个OnSubscribe
接口对象,跟进OnSubscribeLift
:
//第10段代码
public final class OnSubscribeLift<T, R> implements OnSubscribe<R> {
final OnSubscribe parent;
final Operator extends R, ? super T> operator;
public OnSubscribeLift(OnSubscribe 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 parent = new ObserveOnSubscriber(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
第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
应该有了较好的认识,当然它的其他实现原理也很值得我们再深入研究。