这篇文章跟上一篇的RxJava执行流程有关联性,没阅读上一篇的先瞅一下。
首先了解下Scheduler.io()方法,它返回的是一个Scheduler,Scheduler是一个抽象方法,我们知道抽象方法是不能被实例化的,那么返回的肯定是它的实现类:
public static Scheduler io() {
return RxJavaPlugins.onIoScheduler(IO);
}
上面代码里的IO对象是什么呢?
IO = RxJavaPlugins.initIoScheduler(new Callable() {
@Override
public Scheduler call() throws Exception {
return IoHolder.DEFAULT;
}
});
static final class IoHolder {
static final Scheduler DEFAULT = new IoScheduler();
}
答案是IoScheduler对象。
在前面的学习中,我们知道了subscribeOn(Schedulers.io())返回的对象是ObservableSubscribeOb对象
public ObservableSubscribeOn(ObservableSource source, Scheduler scheduler) {
super(source);
this.scheduler = scheduler;
}
@Override
public void subscribeActual(final Observer super T> s) {
final SubscribeOnObserver parent = new SubscribeOnObserver(s);
s.onSubscribe(parent);
parent.setDisposable(scheduler.scheduleDirect(new Runnable() {
@Override
public void run() {
source.subscribe(parent);
}
}));
}
source.subscribe(parent) 被放在一个Runnable中执行,那么他是否已经就在子线程执行了呢?
NO,NO,NO,这还得看Runnable是被放在哪个线程上的,说不定是mainThread呢。
先看看scheduleDirect方法
//无延迟执行
public Disposable scheduleDirect(Runnable run) {
return scheduleDirect(run, 0L, TimeUnit.NANOSECONDS);
}
scheduleDirect.java
public Disposable scheduleDirect(Runnable run, long delay, TimeUnit unit) {
//createWorker是一个抽象方法,创建一个可以可以执行 run 的 worker
final Worker w = createWorker();
//对 run 进行了包装,实际上还是 run 这个对象
final Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
//decoratedRun 交给了 worker 去执行
w.schedule(new Runnable() {
@Override
public void run() {
try {
decoratedRun.run();
} finally {
w.dispose();
}
}
}, delay, unit);
return w;
}
直指IoScheduler#createWorker()
@Override
public Worker createWorker() {
return new EventLoopWorker(pool.get());
}
EventLoopWorker.java
static final class EventLoopWorker extends Scheduler.Worker {
//省略部分code
@Override
public Disposable schedule(Runnable action, long delayTime, TimeUnit unit) {
if (tasks.isDisposed()) {
// don't schedule, we are unsubscribed
return EmptyDisposable.INSTANCE;
}
return threadWorker.scheduleActual(action, delayTime, unit, tasks);
}
}
EventLoopWorker extends Scheduler.Worker ,Worker这个抽象类有个schedule()抽象方法需要重写,所以这个类的核心逻辑就在schedule()方法里:==threadWorker.scheduleActual(action, delayTime, unit, tasks);== ,点击进去看看:
public class NewThreadWorker extends Scheduler.Worker implements Disposable {
//executor 是一个线程池
private final ScheduledExecutorService executor;
volatile boolean disposed;
public NewThreadWorker(ThreadFactory threadFactory) {
executor = SchedulerPoolFactory.create(threadFactory);
}
//省略部分代码
public ScheduledRunnable scheduleActual(final Runnable run, long delayTime, TimeUnit unit, DisposableContainer parent) {
//对传进来的run进行包装
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
ScheduledRunnable里面又做了什么?
@Override
public void run() {
try {
try {
//actual就是通过构造函数传递进来的Runnable
actual.run();
} catch (Throwable e) {
// Exceptions.throwIfFatal(e); nowhere to go
RxJavaPlugins.onError(e);
}
} finally {
Object o = get(PARENT_INDEX);
if (o != DISPOSED && o != null && compareAndSet(PARENT_INDEX, o, DONE)) {
((DisposableContainer)o).delete(this);
}
for (;;) {
o = get(FUTURE_INDEX);
if (o == DISPOSED || compareAndSet(FUTURE_INDEX, o, DONE)) {
break;
}
}
}
}
“故事”的最终还是交给actual.run()去执行,也就是执行==source.subscribe(parent);== 几经“旋转跳跃”,它投入了子线程的怀抱。
切换到子线程的逻辑还是比较容易的,利用线程池而已….
首先了解下AndroidSchedulers.mainThread()
/** A {@link Scheduler} which executes actions on the Android main thread. */
public static Scheduler mainThread() {
return RxAndroidPlugins.onMainThreadScheduler(MAIN_THREAD);
}
private static final Scheduler MAIN_THREAD = RxAndroidPlugins.initMainThreadScheduler(
new Callable() {
@Override public Scheduler call() throws Exception {
return MainHolder.DEFAULT;
}
});
private static final class MainHolder {
static final Scheduler DEFAULT = new HandlerScheduler(new Handler(Looper.getMainLooper()));
}
可以清楚的知道AndroidSchedulers.mainThread()返回的Schedule类是HandlerScheduler,内持有一个可以在主线程发送消息的handler对象。
接下来将代码定位到ObservableObserveOn#subscribeActual()方法
protected void subscribeActual(Observer super T> observer) {
//TrampolineScheduler是在当前线程执行的,但不是立即执行,需要等当前的工作单元都执行结束后。
if (scheduler instanceof TrampolineScheduler) {
source.subscribe(observer);
} else {
//这个schedule是HandlerScheduler,创建了一个 Scheduler.Worker
Scheduler.Worker w = scheduler.createWorker();
source.subscribe(new ObserveOnObserver(observer, w, delayError, bufferSize));
}
}
@Override
public void onNext(T t) {
if (done) {
return;
}
if (sourceMode != QueueDisposable.ASYNC) {
queue.offer(t);
}
//划重点!
schedule();
}
void schedule() {
if (getAndIncrement() == 0) {
worker.schedule(this);
}
}
==getAndIncrement() == 0== 是校验没有原子性,没有多个任务在同时执行
scheduler.createWorker()做了什么?
@Override
public Worker createWorker() {
return new HandlerWorker(handler);
}
private static final class HandlerWorker extends Worker {
private final Handler handler;
private volatile boolean disposed;
HandlerWorker(Handler handler) {
this.handler = handler;
}
@Override
public Disposable schedule(Runnable run, long delay, TimeUnit unit) {
if (run == null) throw new NullPointerException("run == null");
if (unit == null) throw new NullPointerException("unit == null");
if (disposed) {
return Disposables.disposed();
}
run = RxJavaPlugins.onSchedule(run);
ScheduledRunnable scheduled = new ScheduledRunnable(handler, run);
Message message = Message.obtain(handler, scheduled);
message.obj = this; // Used as token for batch disposal of this worker's runnables.
handler.sendMessageDelayed(message, Math.max(0L, unit.toMillis(delay)));
// Re-check disposed state for removing in case we were racing a call to dispose().
if (disposed) {
handler.removeCallbacks(scheduled);
return Disposables.disposed();
}
return scheduled;
}
//省略部分代码
}
在HandlerWorker#schedule()方法里通过Handler发送Message,Message中的callback对应run对象。
我们都知道Handler发送消息后会在dispatchMessage()方法处理
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
private static void handleCallback(Message message) {
message.callback.run();
}
清楚的看到了业务逻辑执行==message.callback.run();== 也就是说ScheduledRunnable会被执行,ScheduledRunnable是ObserveOnObserver#schedule()方法里被传入的。
void schedule() {
if (getAndIncrement() == 0) {
worker.schedule(this);
}
}
它传入的是this,那么最终执行的是ObserveOnObserver#run()方法了。
@Override
public void run() {
//outputFused默认值为false
if (outputFused) {
drainFused();
} else {
drainNormal();
}
}
void drainNormal() {
int missed = 1;
final SimpleQueue q = queue;
final Observer super T> a = actual;
for (;;) {
if (checkTerminated(done, q.isEmpty(), a)) {
return;
}
for (;;) {
boolean d = done;
T v;
try {
v = q.poll();
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
s.dispose();
q.clear();
a.onError(ex);
return;
}
boolean empty = v == null;
if (checkTerminated(d, empty, a)) {
return;
}
if (empty) {
break;
}
a.onNext(v);
}
missed = addAndGet(-missed);
if (missed == 0) {
break;
}
}
}
自上而下看了过来,找到了 ==a.onNext(v);== ,记住它现在所在的是主线程。
切换到子线程的关键是将Runnable放到线程池去执行,切换到主线程是利用在主线程实例化的Handle发送Message,让runnable回调到主线程去。