RxJava2 源码分析笔记(一)
RxJava2 源码分析笔记(二)
终于来到线程切换
先看一个如何切线程的简略流程图
注: 上面蓝牙主流程中 subscribeOn(Schedulers.io()) ,observeOn(AndroidSchedulers.mainThread())
但是subscribeOn,observeOn他们即可以传主线程也可以传子线程
这是让RxJava的线程可以灵活的回切换的关键!
====================================================================
先来看看
这个分为两个部分
|------ subscribeOn() 创建了一个 Runnable{ run{ source.subscribe(parent); } },核心是source.subscribe(parent),并传递 到Schedulers.io()创建的Scheduler中调用。
|------ Schedulers.io()返回一个 Scheduler就是一个用来新建线程并调度使用;
接下来就先看subscribeOn()是如何实现的(和map等数据变换操作一样,结构都是类似的)
/**
* subscribeOn 核心是new ObservableSubscribeOn(this, scheduler)
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.CUSTOM)
public final Observable subscribeOn(Scheduler scheduler) {
ObjectHelper.requireNonNull(scheduler, "scheduler is null");
return RxJavaPlugins.onAssembly(new ObservableSubscribeOn(this, scheduler));
}
ObservableSubscribeOn源码 ↓
public final class ObservableSubscribeOn extends AbstractObservableWithUpstream {
final Scheduler scheduler;
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 SubscribeTask(parent)));
}
static final class SubscribeOnObserver extends AtomicReference implements Observer, Disposable {
//...省略其他代码...
@Override
public void onNext(T t) {
actual.onNext(t);
}
}
//核心代码
final class SubscribeTask implements Runnable {
private final SubscribeOnObserver parent;
SubscribeTask(SubscribeOnObserver parent) {
this.parent = parent;
}
@Override
public void run() {
source.subscribe(parent);
}
}
}
这里面核心代码
public void subscribeActual(final Observer super T> s) {
final SubscribeOnObserver parent = new SubscribeOnObserver(s);
s.onSubscribe(parent);
parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)));
}
首先创建了一个 SubscribeOnObserver
在它的run方法里面执行了source.subscribe(parent); 这样往前回调的subscribe准备好了
final class SubscribeTask implements Runnable {
private final SubscribeOnObserver parent;
SubscribeTask(SubscribeOnObserver parent) {
this.parent = parent;
}
@Override
public void run() {
source.subscribe(parent);
}
}
然后就是将这个Runnable传到调度器中 scheduler.scheduleDirect(new SubscribeTask(parent))
调度器scheduler是哪来的的呢,还记得前面 subscribeOn(Scheduler scheduler)么,它就是我们传递过来的 Schedulers.io() 。
那就看一下 Schedulers.io() 是什么样的
//源码点进去就是这个
@NonNull
public static Scheduler io() {
return RxJavaPlugins.onIoScheduler(IO);
}
而 RxJavaPlugins.onIoScheduler(IO) 返回的就是 IO,我们去看IO就可以了
public final class Schedulers {
......
@NonNull
static final Scheduler IO;
static {
SINGLE = RxJavaPlugins.initSingleScheduler(new SingleTask());
COMPUTATION = RxJavaPlugins.initComputationScheduler(new ComputationTask());
// IO 在这里初始化
IO = RxJavaPlugins.initIoScheduler(new IOTask());
TRAMPOLINE = TrampolineScheduler.instance();
NEW_THREAD = RxJavaPlugins.initNewThreadScheduler(new NewThreadTask());
}
......
}
而 RxJavaPlugins.initIoScheduler(new IOTask()); 最后返回的就是new IOTask()的返回值为啥这么说呢
RxJavaPlugins.initIoSchedule → callRequireNonNull(defaultScheduler)
static Scheduler callRequireNonNull(@NonNull Callable s) {
try {
注释:s就是传递过来的 new IOTask()
return ObjectHelper.requireNonNull(s.call(), "Scheduler Callable result can't be
null");
} catch (Throwable ex) {
throw ExceptionHelper.wrapOrThrow(ex);
}
}
而ObjectHelper.requireNonNull(s.call(), "Scheduler Callable result can't benull");
实现是下面这样的,就是将s.call()不为null原样返回
public final class ObjectHelper {
public static T requireNonNull(T object, String message) {
if (object == null) {
throw new NullPointerException(message);
}
return object;
}
}
s.call 方法返回的 IoHolder.DEFAULT
static final class IOTask implements Callable {
@Override
public Scheduler call() throws Exception {
return IoHolder.DEFAULT;
}
}
而 IoHolder.DEFAULT = new IoScheduler();
static final class IoHolder {
static final Scheduler DEFAULT = new IoScheduler();
}
最终我们得到了一个继承自 Scheduler 的 IoScheduler(IoScheduler源码在下面)
这样两个部分我们都已经得到接下来就看他们之间是如何调用的
调用开始的地方是这行代码:subscribeActual中的scheduler.scheduleDirect(new SubscribeTask(parent))
首先发现 IoScheduler 中并没有 scheduleDirect 方法,是因为这个是在其父类Scheduler 实现的
public abstract class Scheduler {
@NonNull
public Disposable scheduleDirect(@NonNull Runnable run) {
return scheduleDirect(run, 0L, TimeUnit.NANOSECONDS);
}
public abstract Worker createWorker();
public Disposable scheduleDirect(@NonNull Runnable run, long delay, @NonNull TimeUnit
unit) {
核心代码 ↓ createWorker在Scheduler中是抽象方法具体实现在子类IoScheduler中
final Worker w = createWorker();
final Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
DisposeTask task = new DisposeTask(decoratedRun, w);
这里就是子类createWorker得到 Worker w 调用schedule
task就是subscribeOn创建的Runnable
↓
w.schedule(task, delay, unit);
return task;
}
}
public final class IoScheduler extends Scheduler {
注释:createWorker创建并返回了一个EventLoopWorker对象
public Worker createWorker() {
return new EventLoopWorker(pool.get());
}
↓
static final class EventLoopWorker extends Scheduler.Worker {
private final ThreadWorker threadWorker;
EventLoopWorker(CachedWorkerPool pool) {
this.pool = pool;
this.tasks = new CompositeDisposable();
this.threadWorker = pool.get();
}
@NonNull
@Override
public Disposable schedule(@NonNull Runnable action, long delayTime, @NonNull
TimeUnit unit) {
if (tasks.isDisposed()) {
// don't schedule, we are unsubscribed
return EmptyDisposable.INSTANCE;
}
注释: threadWorker = pool.get(),
而pool.get()点进看到返回的是一个ThreadWorker
最终执行的是ThreadWorker.scheduleActual(action, delayTime, unit, tasks)
return threadWorker.scheduleActual(action, delayTime, unit, tasks);
}
}
↓
static final class ThreadWorker extends NewThreadWorker {
private long expirationTime;
注释:但是在ThreadWorker 中并没有scheduleActual
这个方法是在其父类NewThreadWorker中
ThreadWorker(ThreadFactory threadFactory) {
super(threadFactory);
this.expirationTime = 0L;
}
public long getExpirationTime() {
return expirationTime;
}
public void setExpirationTime(long expirationTime) {
this.expirationTime = expirationTime;
}
}
}
下面就看NewThreadWorker 源码
public class NewThreadWorker extends Scheduler.Worker implements Disposable {
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 {
注释: 最后Runnable在这里执行
if (delayTime <= 0) {
f = executor.submit((Callable
到这里subscribeOn(Schedulers.io()),在一个新线程里面.subscribe回去的就实现了
其实和其他操作像flatMap,map差不多,只不过.subscribe是在一个新线程里面执行
上图可以看到: 第一个subscribeOn新建Thread1; 第二个subscribeOn新建Thread2;
在调用链中首先执行第二个subscribeOn切换到Thread2执行了 .subscribe 方法,然后就到了第一个subscribeOn,切换到Thread1,之后的.subscribe和.onNext都是在第一个subscribeOn创建的Thread1线程中执行。所以说只有第一个subscribeOn起作用,之后的subscribeOn也不能说没起作用,执行了.subscribe方法。。。(好像也并没啥有用)。
================================================================
下面就看看
同样也分为两个部分
|------ observeOn() 也是创建了一个 Runnable{ run{ .onNext() } },并传递到
AndroidSchedulers.mainThread()创建的线程中调用。
|------ AndroidSchedulers.mainThread()返回一个线程来执行observeOn创建的Runnable;
先看observeOn
public final Observable observeOn(Scheduler scheduler, boolean delayError, int
bufferSize) {
ObjectHelper.requireNonNull(scheduler, "scheduler is null");
ObjectHelper.verifyPositive(bufferSize, "bufferSize");
return RxJavaPlugins.onAssembly(new ObservableObserveOn(this, scheduler,
delayError, bufferSize));
}
↓
↓
↓ 接着看ObservableObserveOn
↓
↓
↓
public final class ObservableObserveOn extends AbstractObservableWithUpstream {
注释:scheduler就是我们传进来的AndroidSchedulers.mainThread()
final Scheduler scheduler;
public ObservableObserveOn(ObservableSource source, Scheduler scheduler, boolean
delayError, int bufferSize) {
super(source);
this.scheduler = scheduler;
...
}
@Override
protected void subscribeActual(Observer super T> observer) {
if (scheduler instanceof TrampolineScheduler) {
source.subscribe(observer);
} else {
注释:看这里 ↓
Scheduler.Worker w = scheduler.createWorker();
source.subscribe(new ObserveOnObserver(observer, w, delayError,
bufferSize));
}
}
}
Scheduler.Worker w = scheduler.createWorker() 看着有没有很熟悉
source.subscribe(new ObserveOnObserver
接下来就看 ObserveOnObserver 里面的.onNext是如何切换线程传递数据的
注意:ObserveOnObserver实现的了Runnable,
static final class ObserveOnObserver extends BasicIntQueueDisposable
implements Observer, Runnable {
final Scheduler.Worker worker;
ObserveOnObserver(Observer super T> actual, Scheduler.Worker worker, boolean
delayError, int bufferSize) {
this.worker = worker;
...
}
@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);
}
}
public void run() {
if (outputFused) {
drainFused();
} else {
drainNormal();
}
}
void drainNormal() {
...
final Observer super T> a = actual;
for (;;) {
if (checkTerminated(done, q.isEmpty(), a)) {
return;
}
for (;;) {
......
a.onNext(v);
}
......
}
}
}
onNext中执行的是worker.schedule(this);
|------ worker: scheduler.createWorker()
|------ this: 就是实现了Runnable的ObserveOnObserver本身
到这里observeOn就结束了,现在需要找到worker是怎么createWorker出来的。
那接下来就要看传进来的scheduler是啥(其实就是我们传入的AndroidSchedulers.mainThread)。
AndroidSchedulers.mainThread()
public final class AndroidSchedulers {
public static Scheduler mainThread() {
return RxAndroidPlugins.onMainThreadScheduler(MAIN_THREAD);
}
↓
↓ RxAndroidPlugins.onMainThreadScheduler(MAIN_THREAD)返回的就是MAIN_THREAD
↓
private static final Scheduler MAIN_THREAD = RxAndroidPlugins.initMainThreadScheduler(
注释:这里看着也很熟悉,好像和Schedulers.io()差不多
new Callable() {
@Override public Scheduler call() throws Exception {
return MainHolder.DEFAULT;
}
});
↓
↓ 是的没错最后得到的就是MainHolder.DEFAULT
↓
private static final class MainHolder {
static final Scheduler DEFAULT =
new HandlerScheduler(new Handler(Looper.getMainLooper()));
}
}
这样 AndroidSchedulers.mainThread() 我们最后得到就是一个HandlerScheduler对象,new Handler(Looper.getMainLooper())
是作为HandlerScheduler的构造参数传入的。
这样我们就得到了scheduler。
那就看scheduler.createWorker() 是怎么实现的了
final class HandlerScheduler extends Scheduler {
注释:这个handler就是new Handler(Looper.getMainLooper())
private final Handler handler;
HandlerScheduler(Handler handler) {
this.handler = handler;
}
@Override
public Worker createWorker() {
注释1 ↓
return new HandlerWorker(handler);
}
private static final class HandlerWorker extends Worker {
private final Handler handler;
HandlerWorker(Handler handler) {
this.handler = handler;
}
@Override
public Disposable schedule(Runnable run, long delay, TimeUnit unit) {
...
run = RxJavaPlugins.onSchedule(run);
ScheduledRunnable scheduled = new ScheduledRunnable(handler, run);
Message message = Message.obtain(handler, scheduled);
message.obj = this;
handler.sendMessageDelayed(message, unit.toMillis(delay));
...
return scheduled;
}
}
在 createWorker里面返回了 一个HandlerWorker对象,这样worker我们就找到了。
还记得 onNext → schedule()么,schedule中调用worker.schedule(Runnable)
然而HandlerWorker 并没有schedule( Runnable run)方法,因为这个实现是在他的父类Scheduler.Worker中
public abstract class Scheduler {
public abstract static class Worker implements Disposable {
@NonNull
public Disposable schedule(@NonNull Runnable run) {
注释 schedule(run, 0L, TimeUnit.NANOSECONDS)是下面的抽象方法
具体实现在其子类中,所以又回到了原来的HandlerWorker
return schedule(run, 0L, TimeUnit.NANOSECONDS);
}
@NonNull
public abstract Disposable schedule(@NonNull Runnable run, long delay, TimeUnit unit);
}
}
还记得上面HandlerWorker 的源码么
private static final class HandlerWorker extends Worker {
private final Handler handler;
HandlerWorker(Handler handler) {
this.handler = handler;
}
@Override
public Disposable schedule(Runnable run, long delay, TimeUnit unit) {
...
run = RxJavaPlugins.onSchedule(run);
ScheduledRunnable scheduled = new ScheduledRunnable(handler, run);
注释: 核心代码
Message message = Message.obtain(handler, scheduled);
message.obj = this;
handler.sendMessageDelayed(message, unit.toMillis(delay));
...
return scheduled;
}
利用handler将Runnable放在主线程中执行,这样就切换到主线程了(这里我们传的是AndroidSchedulers.mainThread())
这样我们Runnable里面的run方法已经在主线程执行了
这时候我们可以去看一下Runnable(即:ObserveOnObserver)里面的 run 方法是如何执行的
static final class ObserveOnObserver extends BasicIntQueueDisposable
implements Observer, Runnable {
...省略其它代码...
public void run() {
if (outputFused) {
这里执行的是onNext(null)传一个null回去
drainFused();
} else {
执行这里
drainNormal();
}
}
void drainNormal() {
...
final Observer super T> a = actual;
for (;;) {
if (checkTerminated(done, q.isEmpty(), a)) {
return;
}
for (;;) {
......
终于,数据在我们observeOn的线程中传递了回去
a.onNext(v);
}
......
}
}
}
这样observeOn(AndroidSchedulers.mainThread())就结束了。
observeOn之所以可以灵活切换线程核心代码是下面这个
public final class ObservableObserveOn extends AbstractObservableWithUpstream {
@Override
protected void subscribeActual(Observer super T> observer) {
if (scheduler instanceof TrampolineScheduler) {
source.subscribe(observer);
} else {
核心代码
Scheduler.Worker w = scheduler.createWorker();
source.subscribe(new ObserveOnObserver(observer, w, delayError, bufferSize));
}
}
如果你在observeOn中传入 Schedulers.newThread() ,scheduler就是NewThreadScheduler,scheduler.createWorker()得到的就是 NewThreadWorker 然后在在其中 executor.submit(Runnable)。
如果你在observeOn中传入 Schedulers.io() ,scheduler就是IoScheduler,scheduler.createWorker()得到的就是 EventLoopWorker然后在在其中 executor.submit(Runnable)。
如果你在observeOn中传入 AndroidSchedulers.mainThread() ,scheduler就是HandlerScheduler(new Handler(Looper.getMainLooper())),scheduler.createWorker()得到的就是 HandlerWorker然后在在其中执行:
Message message = Message.obtain(handler, scheduled);
message.obj = this;
handler.sendMessageDelayed(message, unit.toMillis(delay));
至此,如何切换线程的就结束了。