从最简单的例子着手,一步步看RxJava内部是如何封装调用的
Flowable.just("hello") .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new FlowableSubscriber<String>() { @Override public void onSubscribe(@NonNull Subscription subscription) { subscription.request(Long.MAX_VALUE); } @Override public void onNext(String s) { textView.append(s+"\n"); } @Override public void onError(Throwable throwable) { } @Override public void onComplete() { } });
这个例子用到了RxJava2的线程切换,最终输出"hello"
1.线程调度器Scheduler
一.先来分析Schedulers.io()
Schedulers可以理解是Scheduler的集合,内部保存了各种类型的Scheduler,方便直接获取。看下io()返回的是什么Scheduler
@NonNull public static Scheduler io() { return RxJavaPlugins.onIoScheduler(IO); }
@NonNull public static Scheduler onIoScheduler(@NonNull Scheduler defaultScheduler) { Function f = onIoHandler; //onIoHandler默认是null return f == null?defaultScheduler:(Scheduler)apply(f, defaultScheduler); }看出io()直接返回IO这个Scheduler
@NonNull static final Scheduler IO = RxJavaPlugins.initIoScheduler(new Schedulers.IOTask());##这里先看下传入的参数IOTask是什么
static final class IOTask implements Callable<Scheduler> { IOTask() { } public Scheduler call() throws Exception { return Schedulers.IoHolder.DEFAULT; } }
##它继承并实现了Callable接口(Callable和Runnable都是用于多线程的接口,区别是一个有返回值,一个没有)
回头看initIoScheduler方法
@NonNull public static Scheduler initIoScheduler(@NonNull Callable<Scheduler> defaultScheduler) { ObjectHelper.requireNonNull(defaultScheduler, "Scheduler Callable can\'t be null"); Function f = onInitIoHandler; //默认是null return f == null?callRequireNonNull(defaultScheduler):applyRequireNonNull(f, defaultScheduler); }
@NonNull static Scheduler callRequireNonNull(@NonNull Callable<Scheduler> s) { try { return (Scheduler)ObjectHelper.requireNonNull(s.call(), "Scheduler Callable result can\'t be null"); //关键s.call() } catch (Throwable var2) { throw ExceptionHelper.wrapOrThrow(var2); } }最终返回的是s.call()方法的返回值即Schedulers.IoHolder.DEFAULT,所以Schedulers.io()其实获取的就是Schedulers.IoHolder.DEFAULT,下面看看这个DEFAULT是什么调度器
static final class IoHolder { static final Scheduler DEFAULT = new IoScheduler(); IoHolder() { } }
public final class IoScheduler extends Scheduler { ... public IoScheduler() { this(WORKER_THREAD_FACTORY); } public IoScheduler(ThreadFactory threadFactory) { this.threadFactory = threadFactory; this.pool = new AtomicReference(NONE); this.start(); } static { KEEP_ALIVE_UNIT = TimeUnit.SECONDS; SHUTDOWN_THREAD_WORKER = new IoScheduler.ThreadWorker(new RxThreadFactory("RxCachedThreadSchedulerShutdown")); //RxThreadFactory是自定义线程工厂,主要作了设置线程名称、优先级、将线程设为守护线程等辅助行为 SHUTDOWN_THREAD_WORKER.dispose(); //调用ScheduledThreadPoolExctuor.shutdownNow(),作用是立即关闭线程池 int priority = Math.max(1, Math.min(10, Integer.getInteger("rx2.io-priority", 5).intValue())); //这里计算出来的优先级是5 WORKER_THREAD_FACTORY = new RxThreadFactory("RxCachedThreadScheduler", priority); EVICTOR_THREAD_FACTORY = new RxThreadFactory("RxCachedWorkerPoolEvictor", priority); NONE = new IoScheduler.CachedWorkerPool(0L, (TimeUnit)null, WORKER_THREAD_FACTORY); NONE.shutdown(); //关闭线程池 } ... }
##详细分析初始化做了哪些操作
1)静态代码块
- SHUTDOWN_THREAD_WORKER:实例化一个ThreadWorker,继承NewThreadWorker,又继承Worker(Worker是RxJava定义的类,通过它调用Runnable)。在NewThreadWorker的构造方法中实例化了一个ScheduledThreadPoolExecutor(用于多线程下定时/延迟任务的执行),并缓存进SchedulerPoolFactory.POOLS中
- NONE:实例化CacheWorkerPool,该类继承并实现Runnable接口。构造方法中也创建并保存了一个ScheduledThreadPoolExecutor
2)构造方法
- pool:创建AtomicReference对象,初始化它的值为NONE
- start():该方法就是重新new了一个CacheWorkerPool,keepAliveTime为60,替换pool中的值为它
private static final Scheduler MAIN_THREAD = RxAndroidPlugins.initMainThreadScheduler( new Callable<Scheduler>() { @Override public Scheduler call() throws Exception { return MainHolder.DEFAULT; } }); /** A {@link Scheduler} which executes actions on the Android main thread. */ public static Scheduler mainThread() { return RxAndroidPlugins.onMainThreadScheduler(MAIN_THREAD); //这里直接返回MAIN_THREAD }内部经过各种转换比较最终会返回MainHolder.DEFAULT对象
private static final class MainHolder { static final Scheduler DEFAULT = new HandlerScheduler(new Handler(Looper.getMainLooper())); }AndroidSchedulers.mainThread()创建返回的是HandlerScheduler对象,其继承Scheduler,内部保存了Android主线程的Handler。
2.subscribeOn指定订阅时所在的线程
进入subcribeOn查看源码
@CheckReturnValue @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport("custom") public final Flowable<T> subscribeOn(@NonNull Scheduler scheduler) { ObjectHelper.requireNonNull(scheduler, "scheduler is null"); return this.subscribeOn(scheduler, !(this instanceof FlowableCreate)); //传入IoScheduler和true }
@CheckReturnValue @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport("custom") @Experimental public final Flowable<T> subscribeOn(@NonNull Scheduler scheduler, boolean requestOn) { ObjectHelper.requireNonNull(scheduler, "scheduler is null"); return RxJavaPlugins.onAssembly(new FlowableSubscribeOn(this, scheduler, requestOn)); //这里原样返回FlowableSubscribeOn对象 }看出该方法创建了FlowableSubscribeOn,传入FlowableJust自身、IoScheduler、true包装保存,该对象也继承自Flowable。
public FlowableSubscribeOn(Flowable<T> source, Scheduler scheduler, boolean nonScheduledRequests) { super(source); this.scheduler = scheduler; this.nonScheduledRequests = nonScheduledRequests; }
执行完subscribeOn方法这里返回的是一个FlowableSubscribeOn对象,这个对象保存了上游传下来的FlowableJust和IoScheduler。
3.observeOn切换线程
进入方法内部
@CheckReturnValue @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport("custom") public final Flowable<T> observeOn(Scheduler scheduler, boolean delayError, int bufferSize) { //传入的delayError为false,bufferSize为128 ObjectHelper.requireNonNull(scheduler, "scheduler is null"); ObjectHelper.verifyPositive(bufferSize, "bufferSize"); return RxJavaPlugins.onAssembly(new FlowableObserveOn(this, scheduler, delayError, bufferSize)); }创建并 返回 FlowableObserveOn对象,该对象保存了上游传下来的FlowableSubscribeOn和HandlerScheduler。
public FlowableObserveOn(Flowable<T> source, Scheduler scheduler, boolean delayError, int prefetch) { super(source); //FlowableSubscribeOn this.scheduler = scheduler; //HandlerScheduler this.delayError = delayError; //false this.prefetch = prefetch; //128 }
4.subscribe订阅
接下来就是执行订阅的方法了,真正执行订阅的地方在FlowableObserveOn.subscribeActual方法中
public void subscribeActual(Subscriber<? super T> s) { Worker worker = this.scheduler.createWorker(); //调用HandlerScheduler,返回HandlerWorker if(s instanceof ConditionalSubscriber) { //s是FlowableSubscriber,比较结果是false this.source.subscribe(new FlowableObserveOn.ObserveOnConditionalSubscriber((ConditionalSubscriber)s, worker, this.delayError, this.prefetch)); } else { this.source.subscribe(new FlowableObserveOn.ObserveOnSubscriber(s, worker, this.delayError, this.prefetch)); //调用FlowableSubscribeOn的subscribe方法;ObserveOnSubscriber对象将我们实现的FlowableSubscriber、HandlerWorker、FlowableObserveOn、false、128等参数包装进去后面用到 } }
现在执行到了FlowableSubscribeOn的subscribe方法,这个方法实际执行subscribeActual方法,
分析里面做了哪些操作:
public void subscribeActual(Subscriber<? super T> s) { Worker w = this.scheduler.createWorker(); //调用IoScheduler的createWorker方法,返回EventLoopWorker对象 FlowableSubscribeOn.SubscribeOnSubscriber sos = new FlowableSubscribeOn.SubscribeOnSubscriber(s, w, this.source, this.nonScheduledRequests); //创建SubscribeOnSubscriber对象,将ObserveOnSubscriber、EventLoopWorker、FlowableJust、true传入 s.onSubscribe(sos); w.schedule(sos); }
1)s.onSubscribe(sos); 即ObserveOnSubscriber.onSubscribe(SubscribeOnSubscriber)
public void onSubscribe(Subscription s) { if(SubscriptionHelper.validate(this.s, s)) { this.s = s; if(s instanceof QueueSubscription) { //比较结果为false QueueSubscription f = (QueueSubscription)s; int m = f.requestFusion(7); if(m == 1) { this.sourceMode = 1; this.queue = f; this.done = true; this.actual.onSubscribe(this); return; } if(m == 2) { this.sourceMode = 2; this.queue = f; this.actual.onSubscribe(this); s.request((long)this.prefetch); return; } } this.queue = new SpscArrayQueue(this.prefetch); this.actual.onSubscribe(this); s.request((long)this.prefetch); } }看倒数第二句,this.actual就是我们创建的FlowableSubscriber,在onSubscribe方法中执行subscription.request(Long.MAX_VALUE)。查看ObserveOnSubscriber的request代码:
public final void request(long n) { if(SubscriptionHelper.validate(n)) { BackpressureHelper.add(this.requested, n); //RxJava的一种背压策略 this.trySchedule(); //关键看这句,调用了实例化时保存的HandlerWorker的schedule方法 } }
final void trySchedule() { if(this.getAndIncrement() == 0) { //原子操作,这里相当于i++ this.worker.schedule(this); //worker是HandlerWorker } }
schedule方法先调用的父类Worker的schedule,然后再调用HandlerWorker的schedule
@Override public Disposable schedule(Runnable run, long delay, TimeUnit unit) { if (run == null) throw new NullPointerException("run == null"); //这里的run即ObserveOnSubscriber if (unit == null) throw new NullPointerException("unit == null"); if (disposed) { return Disposables.disposed(); } run = RxJavaPlugins.onSchedule(run); //这里原样返回 ScheduledRunnable scheduled = new ScheduledRunnable(handler, run); //把主线程Handler和ObserveOnSubscriber包装进去 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))); //这里延迟0,立即发送,在主线程响应 // 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; }
2)w.schedule(sos); 即EventLoopWorker.schedule(SubscribeOnSubscriber),最终会调用
@NonNull
public Disposable schedule(@NonNull Runnable action, long delayTime, @NonNull TimeUnit unit) { //isDisposed默认false
return (Disposable)(this.tasks.isDisposed()?EmptyDisposable.INSTANCE:this.threadWorker.scheduleActual(action, delayTime, unit, this.tasks));
}
又调用threadWorker的父类中的scheduleActual方法
@NonNull public ScheduledRunnable scheduleActual(Runnable run, long delayTime, @NonNull TimeUnit unit, @Nullable DisposableContainer parent) { Runnable decoratedRun = RxJavaPlugins.onSchedule(run); //这里原样返回 ScheduledRunnable sr = new ScheduledRunnable(decoratedRun, parent); //将SubscribeOnSubscriber包装进去 if(parent != null && !parent.add(sr)) { //parent非空、add返回true return sr; } else { try { Object f; if(delayTime <= 0L) { //delayTime=0 f = this.executor.submit(sr); //交由ScheduledThreadPoolExecutor线程池运行 } else { f = this.executor.schedule(sr, delayTime, unit); } sr.setFuture((Future)f); } catch (RejectedExecutionException var10) { if(parent != null) { parent.remove(sr); } RxJavaPlugins.onError(var10); } return sr; } }该方法中ScheduledRunnable在线程池的线程中运行,它的run方法中又调用了 SubscribeOnSubscriber的run方法
public void run() { this.lazySet(Thread.currentThread()); Publisher src = this.source; this.source = null; src.subscribe(this); //src即最开始just方法创建返回的FlowableJust对象 }此时已经是在另一个线程中执行了,即真正开始订阅的时候是在Schedulers.io()指定的线程中了
继续往下执行,会调用FlowableJust.subscribeActual->SubscribeOnSubscriber.onSubscribe方法->SubscribeOnSubscriber.requestUpStream方法->ScalarSubscription.request方法:
public void request(long n) { //n=128 if(SubscriptionHelper.validate(n)) { if(this.compareAndSet(0, 1)) { //经过CAS值为1 Subscriber s = this.subscriber; //s即SubscribeOnSubscriber s.onNext(this.value); //value="hello" if(this.get() != 2) { s.onComplete(); } } } }s.onNext->SubscribeOnSubscriber.onNext->ObserveOnSubscriber的父类的onNext:
public final void onNext(T t) { if(!this.done) { if(this.sourceMode == 2) { //这里sourceMode=0 this.trySchedule(); } else { if(!this.queue.offer(t)) { //关键,这里将"hello"加入q队列,返回true this.s.cancel(); this.error = new MissingBackpressureException("Queue is full?!"); this.done = true; } this.trySchedule(); //该方法上面分析过 } } }s.onComplete-> SubscribeOnSubscriber.onComplete->FlowableOnSubscriber.onComplete
public void onComplete() { this.actual.onComplete(); this.worker.dispose(); //处理释放EventLoopWorker }
public final void onComplete() { if(!this.done) { this.done = true; this.trySchedule(); //该方法上面分析过 } }trySchedule方法会调用实例化时保存的XXWorker对象(这个例子中是HandlerWorker)的schedule方法,该方法会将包装过的Runnable通过Handler消息机制发送到Looper的线程执行。
在这个例子中
ScheduledRunnable scheduled = new ScheduledRunnable(handler, run); //把主线程Handler和ObserveOnSubscriber包装进去 Message message = Message.obtain(handler, scheduled);
handler发送消息后,等待MainLooper取出队列中的消息处理,通过Handler机制实现切换到主线程运行。因为message的callback为ScheduledRunnable,所以调用了ScheduledRunnable的run方法,它的run方法又调用了传入的ObserveOnSubscriber的run方法(该run方法在父类中):
public final void run() { if(this.outputFused) { //默认false this.runBackfused(); } else if(this.sourceMode == 1) { //默认0 this.runSync(); } else { this.runAsync(); //该方法在子类实现 } }最终执行
void runAsync() { int missed = 1; Subscriber a = this.actual; SimpleQueue q = this.queue; //该队列会存放上游传进来的数据 long e = this.produced; while(true) { long r = this.requested.get(); while(e != r) { boolean w = this.done; Object v; try { v = q.poll(); //从队列中取出数据 } catch (Throwable var11) { Exceptions.throwIfFatal(var11); this.s.cancel(); q.clear(); a.onError(var11); this.worker.dispose(); return; } boolean empty = v == null; if(this.checkTerminated(w, empty, a)) { //关键,该方法根据done和数据是否空判断是否退出循环 return; } if(empty) { break; } a.onNext(v); //关键,调用了我们创建的FlowableSubscriber的onNext,并传入"hello" ++e; if(e == (long)this.limit) { if(r != 9223372036854775807L) { r = this.requested.addAndGet(-e); } this.s.request(e); e = 0L; } } if(e == r && this.checkTerminated(this.done, q.isEmpty(), a)) { return; } int var12 = this.get(); if(missed == var12) { this.produced = e; missed = this.addAndGet(-missed); if(missed == 0) { return; } } else { missed = var12; } } }
checkTerminated方法根据done标识和队列有无数据判断是否完成,在该方法内部最终调用我们创建的FlowableSubscriber的onComplete方法。
RxJava2通过层层包装和回调,实现了强大的功能。以上就是这个例子中,代码内部的大致调用流程。如有错误,请指正。