简单了解
Rx是Reactive Extensions,RxJava就是响应式扩展在Java上的实现。
它主要通过观察者模式解决了接口回调嵌套阅读复杂的问题,实现链式调用简洁易读的特点。它还实现了适合不同任务的线程,像计算型,IO型,普通型,方便用户选择。
看一下RxJava一般情况下的使用方式,例子如下:
Observable.create(emit -> {
Thread.sleep(5000);
emit.onNext("1");
})
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<Object>() {
@Override
public void accept(Object o) throws Throwable {
Log.e("MainActivity", "接收到数据:" + o.toString());
}
});
如上,create里的Lambda表达式,一般情况下,是一个费时操作,不能放到主线程中,这时通过subscribeOn来指定对应线程调度器,这块现在是Schedulers.newThread(),使用普通线程。
observeOn也是指定线程调度器,这里是AndroidSchedulers.mainThread(),意思是使用主线程处理对应任务。它处理的是哪个任务呢,subscribe订阅的任务。
下面就根据上面这段代码来分析一下它的原理。
相关类
先认识一下关键的类,如下:
Observable:被观察者类,被观察者会继承该类。它在订阅观察者时,会调用subscribe(@NonNull Observer<? super T> observer)方法,不过该方法在Observable类中被声明成final,所以子类不能重写该方法,应该重写subscribeActual(@NonNull Observer<? super T> observer)方法,它会在subscribe()方法中被调用。Observable类里还声明了许多操作符方法。
Observer:观察者类接口,观察者会继承该类。
ObservableOnSubscribe:它是一个接口,里面有一个待实现方法subscribe(@NonNull ObservableEmitter emitter)。注意它的参数类型是ObservableEmitter接口类型,它又实现Emitter接口,Emitter接口有三个方法,onNext(@NonNull T value),onError(@NonNull Throwable error),onComplete()。ObservableOnSubscribe对应着上面举例中create()方法里面的Lambda表达式,实现的就是它的subscribe(@NonNull ObservableEmitter emitter)。虽然它没继承Observable,但它应该归为被观察者。
ObservableCreate:继承Observable,属于被观察者。它是通过Observable.create()方法生成的,在这个例子中,它的成员source是ObservableOnSubscribe对象。
ObservableSubscribeOn:继承Observable,属于被观察者。在例子中,它是调用subscribeOn()生成的,这里是将ObservableCreate对象和Schedulers.newThread()封装到它的成员变量里面。
ObservableObserveOn:继承Observable,属于被观察者。例子中,它是调用observeOn()生成的,它的成员变量也包括ObservableSubscribeOn对象,AndroidSchedulers.mainThread()调度器。
通过上面这几个类对象的链式调用,我们发现后面生成的被观察者对象总是包含前面的被观察者对象,这其实使用的是组合的设计方式。
LambdaObserver:继承Observer对象,属于观察者。例子中的链式最后一步调用的是subscribe()方法,参数是实现的Consumer接口,其实最终会将Consumer对象封装到LambdaObserver对象中。LambdaObserver对象有4个成员变量,1、Consumer<? super T> onNext,2、Consumer<? super Throwable> onError,3、Action onComplete,4、Consumer<? super Disposable> onSubscribe。其中onNext就是例子中的Consumer接口对象。
SubscribeOnObserver:继承Observer,是观察者类。它是在ObservableSubscribeOn类中订阅方法subscribeActual()中生成的,它的成员变量downstream也是指向一个观察者对象。
NewThreadScheduler:普通线程调度器
HandlerScheduler:Android主线程调度器
ComputationScheduler:计算型任务调度器
IoScheduler:IO型任务调度器
NewThreadWorker:它里面维护了线程池,线程执行都是通过它。
Scheduler.Worker:它是一层封装,它里面包含着NewThreadWorker或者其子类成员,通过它来传递任务。
代码流程
按照例子的代码,看一下整个流程
再看一下类结构组合引用图
从上面的图可以看出,每个类对象都包含着它前面的那个对象。
下面就结合代码来理解一下上面的流程。
1、创建ObservableCreate类对象
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Observable<T> create(@NonNull ObservableOnSubscribe<T> source) {
Objects.requireNonNull(source, "source is null");
return RxJavaPlugins.onAssembly(new ObservableCreate<>(source));
}
可见将ObservableOnSubscribe类对象source设置到新创建ObservableCreate对象的成员变量中。
它还会调用RxJavaPlugins.onAssembly()函数,
@NonNull
public static <@NonNull T> Observable<T> onAssembly(@NonNull Observable<T> source) {
Function<? super Observable, ? extends Observable> f = onObservableAssembly;
if (f != null) {
return apply(f, source);
}
return source;
}
……
@NonNull
static <@NonNull T, @NonNull R> R apply(@NonNull Function<T, R> f, @NonNull T t) {
try {
return f.apply(t);
} catch (Throwable ex) {
throw ExceptionHelper.wrapOrThrow(ex);
}
}
可见,如果RxJavaPlugins类的静态成员onObservableAssembly被设置过,还会调用它来处理一下前面新生成的ObservableCreate对象。而这里如果设置onObservableAssembly,需要用RxJavaPlugins类的setOnObservableAssembly(),目前我们是没有设置过。RxJavaPlugins类里还设置了好多其他的类似的成员函数,在它这里叫钩子函数。是为了让用户能做一些处理,用户可以实现它。
2、创建ObservableSubscribeOn类对象
接着需要调用ObservableCreate的subscribeOn(@NonNull Scheduler scheduler),不过它并没有实现该方法,它的实现在Observable类中
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.CUSTOM)
@NonNull
public final Observable<T> subscribeOn(@NonNull Scheduler scheduler) {
Objects.requireNonNull(scheduler, "scheduler is null");
return RxJavaPlugins.onAssembly(new ObservableSubscribeOn<>(this, scheduler));
}
可以看到,也是调用了ObservableSubscribeOn的构造函数,这里将ObservableCreate对象和Scheduler对象设置到ObservableSubscribeOn类对象的成员变量中。
在这个步骤之前,会先创建Scheduler对象,还是拿前面举的例子中的Schedulers.newThread()来说,看它的代码:
@NonNull
static final Scheduler NEW_THREAD;
…………
static {
…………
NEW_THREAD = RxJavaPlugins.initNewThreadScheduler(new NewThreadTask());
}
…………
@NonNull
public static Scheduler newThread() {
return RxJavaPlugins.onNewThreadScheduler(NEW_THREAD);
}
可见,在Schedulers类加载的时候,就会创建NEW_THREAD,以后每次调用newThread(),都会返回NEW_THREAD。RxJavaPlugins.onNewThreadScheduler()也是钩子函数,这里没有设置。
接着看NEW_THREAD 的创建,
static final class NewThreadTask implements Supplier<Scheduler> {
@Override
public Scheduler get() {
return NewThreadHolder.DEFAULT;
}
}
…………
static final class NewThreadHolder {
static final Scheduler DEFAULT = new NewThreadScheduler();
}
NewThreadHolder.DEFAULT是通过NewThreadScheduler类的构造函数来生成对象。
这样以后再调用Schedulers.newThread()就直接返回NewThreadHolder.DEFAULT对象了。
3、创建ObservableObserveOn类对象
现在应该调用ObservableSubscribeOn的observeOn()方法,它实现在Observable 类里面:
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.CUSTOM)
@NonNull
public final Observable<T> observeOn(@NonNull Scheduler scheduler) {
return observeOn(scheduler, false, bufferSize());
}
…………
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.CUSTOM)
@NonNull
public final Observable<T> observeOn(@NonNull Scheduler scheduler, boolean delayError, int bufferSize) {
Objects.requireNonNull(scheduler, "scheduler is null");
ObjectHelper.verifyPositive(bufferSize, "bufferSize");
return RxJavaPlugins.onAssembly(new ObservableObserveOn<>(this, scheduler, delayError, bufferSize));
}
代码也是和上面类似,生成ObservableObserveOn对象,将ObservableSubscribeOn对象,Scheduler 对象,delayError,bufferSize作为参数封装到ObservableObserveOn对象里面。bufferSize是它里面的实现的单一生产者消费者队列的大小的一个参考值,这里大小为128。
在这个步骤之前,会先创建Scheduler对象,还是拿前面举的例子中的
AndroidSchedulers.mainThread()
private static final class MainHolder {
static final Scheduler DEFAULT = internalFrom(Looper.getMainLooper(), true);
}
private static final Scheduler MAIN_THREAD =
RxAndroidPlugins.initMainThreadScheduler(() -> MainHolder.DEFAULT);
…………
public static Scheduler mainThread() {
return RxAndroidPlugins.onMainThreadScheduler(MAIN_THREAD);
}
该方法得到的也是静态变量MAIN_THREAD,它是通过internalFrom()方法得到的
@SuppressLint("NewApi") // Checking for an @hide API.
private static Scheduler internalFrom(Looper looper, boolean async) {
// Below code exists in androidx-core as well, but is left here rather than include an
// entire extra dependency.
// https://developer.android.com/reference/kotlin/androidx/core/os/MessageCompat?hl=en#setAsynchronous(android.os.Message,%20kotlin.Boolean)
if (Build.VERSION.SDK_INT < 16) {
async = false;
} else if (async && Build.VERSION.SDK_INT < 22) {
// Confirm that the method is available on this API level despite being @hide.
Message message = Message.obtain();
try {
message.setAsynchronous(true);
} catch (NoSuchMethodError e) {
async = false;
}
message.recycle();
}
return new HandlerScheduler(new Handler(looper), async);
}
这里创建了HandlerScheduler对象,这里面封装了Handler对象,还有async参数,它代表发送的消息Message 是否是异步消息,根据系统版本的不同做了适配。
这里生成的Handler的looper是Looper.getMainLooper(),代表Handler处理接收到的消息是在主线程处理的。
这样通过链式层层组合,生成了ObservableObserveOn对象。
通过第2、3步指定了2个任务调度器。在Android里面耗时的操作一般都是不能放在主线程中执行的,所以第2步的任务调度,是将耗时操作放到新线程中去执行。而耗时结果执行完毕之后,会将执行结果返回给主线程,所以第3步就是切换回主线程中去处理对应结果。
接着往下看,具体的线程调度,它实现在subscribe()方法中。
4、订阅观察者
例子中是subscribe了一个Consumer对象,最终它会调用到Observable类文件中如下方法:
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@NonNull
public final Disposable subscribe(@NonNull Consumer<? super T> onNext) {
return subscribe(onNext, Functions.ON_ERROR_MISSING, Functions.EMPTY_ACTION);
}
…………
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@NonNull
public final Disposable subscribe(@NonNull Consumer<? super T> onNext, @NonNull Consumer<? super Throwable> onError,
@NonNull Action onComplete) {
Objects.requireNonNull(onNext, "onNext is null");
Objects.requireNonNull(onError, "onError is null");
Objects.requireNonNull(onComplete, "onComplete is null");
LambdaObserver<T> ls = new LambdaObserver<>(onNext, onError, onComplete, Functions.emptyConsumer());
subscribe(ls);
return ls;
}
可以看到Consumer对象被封装到LambdaObserver中,并且LambdaObserver对象的成员变量onError设置为Functions.ON_ERROR_MISSING,将onComplete设置为Functions.EMPTY_ACTION,将onSubscribe设置为Functions.emptyConsumer(),接着又调用了subscribe(ls)。
@SchedulerSupport(SchedulerSupport.NONE)
@Override
public final void subscribe(@NonNull Observer<? super T> observer) {
Objects.requireNonNull(observer, "observer is null");
try {
observer = RxJavaPlugins.onSubscribe(this, observer);
Objects.requireNonNull(observer, "The RxJavaPlugins.onSubscribe hook returned a null Observer. Please change the handler provided to RxJavaPlugins.setOnObservableSubscribe for invalid null returns. Further reading: https://github.com/ReactiveX/RxJava/wiki/Plugins");
subscribeActual(observer);
} catch (NullPointerException e) { // NOPMD
throw e;
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
// can't call onError because no way to know if a Disposable has been set or not
// can't call onSubscribe because the call might have set a Subscription already
RxJavaPlugins.onError(e);
NullPointerException npe = new NullPointerException("Actually not, but can't throw other exceptions due to RS");
npe.initCause(e);
throw npe;
}
}
他会调用钩子函数RxJavaPlugins.onSubscribe(),不过这个需要设置,目前是没有设置状态,继续调用subscribeActual(observer),我们知道当前具体实例类型是ObservableObserveOn对象,下面看一下该类的subscribeActual(observer)方法:
@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不是TrampolineScheduler类型,所以会调用scheduler.createWorker()创建了一个Worker 对象,然后封装到一个ObserveOnObserver对象里面。这例子里,scheduler是HandlerScheduler对象,observer是LambdaObserver对象。source是ObservableSubscribeOn对象,前面也说过,被观察对象的subscribe()方法,最终会调用到ObservableSubscribeOn类的subscribeActual(),看一下它的代码:
@Override
public void subscribeActual(final Observer<? super T> observer) {
final SubscribeOnObserver<T> parent = new SubscribeOnObserver<>(observer);
observer.onSubscribe(parent);
parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)));
}
这里先将参数封装到SubscribeOnObserver对象里,然后调用参数的observer.onSubscribe(parent),再将刚才生成的SubscribeOnObserver对象封装到SubscribeTask对象中,接着会调用线程调度器对象的scheduleDirect(),最后将scheduleDirect()生成的对象设置到SubscribeOnObserver对象里。
ObserveOnObserver被订阅
在这里observer是ObserveOnObserver对象,看一下它的onSubscribe(parent)
@Override
public void onSubscribe(Disposable d) {
if (DisposableHelper.validate(this.upstream, d)) {
this.upstream = d;
…………
queue = new SpscLinkedArrayQueue<>(bufferSize);
downstream.onSubscribe(this);
}
}
这里upstream 是Disposable类引用,刚开始时是null,DisposableHelper.validate(this.upstream, d)是判断upstream为null时,返回true。接着就将this.upstream设置为参数d,d在这里是SubscribeOnObserver对象。其实,如果this.upstream不为null,DisposableHelper.validate()会调用reportDisposableSet()方法,它会抛出异常ProtocolViolationException(“Disposable already set!”),可见一个观察者不能被多次订阅。
接着生成SpscLinkedArrayQueue对象,它是一个单一生产者单一消费者队列。再调用downstream的onSubscribe(),在这里downstream是LambdaObserver对象,再看一下它的onSubscribe()
LambdaObserver被订阅
@Override
public void onSubscribe(Disposable d) {
if (DisposableHelper.setOnce(this, d)) {
try {
onSubscribe.accept(this);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
d.dispose();
onError(ex);
}
}
}
在这里参数是ObserveOnObserver 对象,LambdaObserver 是继承AtomicReference,DisposableHelper.setOnce(this, d)检查它如果没有被设置过,则会将它设置为d,并且返回true。接着会调用onSubscribe.accept(this),这里onSubscribe,通过签名构造LambdaObserver 对象时知,onSubscribe为Functions.emptyConsumer(),它为一个空实现。
调度器调度线程
返回到ObservableSubscribeOn类的subscribeActual(),执行完ObserveOnObserver的onSubscribe(parent),需要执行scheduler.scheduleDirect()。scheduler是NewThreadScheduler对象。不过scheduleDirect()方法实现在Schduler类中。
@NonNull
public Disposable scheduleDirect(@NonNull Runnable run) {
return scheduleDirect(run, 0L, TimeUnit.NANOSECONDS);
}
…………
@NonNull
public Disposable scheduleDirect(@NonNull Runnable run, long delay, @NonNull TimeUnit unit) {
final Worker w = createWorker();
final Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
DisposeTask task = new DisposeTask(decoratedRun, w);
w.schedule(task, delay, unit);
return task;
}
叫Schduler为线程调度器,关键的代码也就是在这里。
1、调用createWorker()创建一个Worker 对象。
2、将Runnable 对象decoratedRun和Worker 对象w封装成DisposeTask 对象。
3、调用Worker 对象的schedule()方法。
创建Worker 对象
createWorker()在Schduler类中是抽象函数,它的实现在子类中。由于scheduler是NewThreadScheduler对象,看一下它的的实现
@NonNull
@Override
public Worker createWorker() {
return new NewThreadWorker(threadFactory);
}
threadFactory是一个静态变量,它是线程工厂。创建线程的优先级,如果没有在对应属性中设置,则为Thread.NORM_PRIORITY。可见NewThreadScheduler调度器生成的线程都是普通线程。
NewThreadWorker对象里面有一个成员变量executor,它是ScheduledExecutorService,实际类型是ScheduledThreadPoolExecutor,一个线程池。
public static ScheduledExecutorService create(ThreadFactory factory) {
final ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1, factory);
exec.setRemoveOnCancelPolicy(PURGE_ENABLED);
return exec;
}
…………
…………
public ScheduledThreadPoolExecutor(int corePoolSize,
ThreadFactory threadFactory) {
super(corePoolSize, Integer.MAX_VALUE,
DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
new DelayedWorkQueue(), threadFactory);
}
它的核心线程数是1,最大线程数是Integer.MAX_VALUE,多余的线程完成任务空闲10ms被回收,它的存储队列为DelayedWorkQueue。我们知道DelayedWorkQueue是一个根据延时长短调度任务的线程,并且任务队列大小没有限制,并且核心线程就只有一个,这会导致再多的任务也只会在一个线程中执行。
新线程中调度任务
看一下NewThreadWorker的schedule()方法
@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;
}
参数run现在是SubscribeTask对象,它里面包含SubscribeOnObserver对象。
首先还是调用RxJavaPlugins.onSchedule(run),来处理一下run,不过这里没有设置相应的方法,所以,还是返回它本身。
接着将decoratedRun和parent封装到ScheduledRunnable对象中,ScheduledRunnable继承AtomicReferenceArray,实现了Runnable, Callable。它的AtomicReferenceArray的长度为3。0位置放置父容器,就是初始化传进来的parent。1位置放置FUTURE位置,它是线程池执行Callable时返回的对象,2位置放的是线程池运行起来的线程对象。
再接着,如果参数parent参数不为null,会把生成的ScheduledRunnable对象添加到父容器parent中。
紧接着就是线程池调度对应的任务,创建新线程执行任务。
最后调用ScheduledRunnable的setFuture(f)。
创建新线程,调度任务
前面说了,executor是ScheduledThreadPoolExecutor线程池,在这里会调用它的submit()方法,执行了它之后。会调用sr的call()方法。
public Object call() {
// Being Callable saves an allocation in ThreadPoolExecutor
run();
return null;
}
@Override
public void run() {
lazySet(THREAD_INDEX, Thread.currentThread());
try {
try {
actual.run();
} catch (Throwable e) {
// Exceptions.throwIfFatal(e); nowhere to go
RxJavaPlugins.onError(e);
throw e;
}
} finally {
Object o = get(PARENT_INDEX);
if (o != PARENT_DISPOSED && compareAndSet(PARENT_INDEX, o, DONE) && o != null) {
((DisposableContainer)o).delete(this);
}
for (;;) {
o = get(FUTURE_INDEX);
if (o == SYNC_DISPOSED || o == ASYNC_DISPOSED || compareAndSet(FUTURE_INDEX, o, DONE)) {
break;
}
}
lazySet(THREAD_INDEX, null);
}
}
call()开始执行时,它已经在新线程中了。call()继续调用run(),可以看到ScheduledRunnable的lazySet(THREAD_INDEX, Thread.currentThread()),将THREAD_INDEX设置为它运行的线程对象。
接着调用actual.run(),这里actual是在ObservableSubscribeOn类的subscribeActual(final Observer<? super T> observer)里生成的SubscribeTask对象。SubscribeTask类是ObservableSubscribeOn的内部类,看一下SubscribeTask类的run()。
@Override
public void run() {
source.subscribe(parent);
}
source是来自ObservableSubscribeOn类,在这里是ObservableCreate类对象。parent则是SubscribeOnObserver对象。继续看ObservableCreate类的subscribe(),它会调用subscribeActual()方法:
@Override
protected void subscribeActual(Observer<? super T> observer) {
CreateEmitter<T> parent = new CreateEmitter<>(observer);
observer.onSubscribe(parent);
try {
source.subscribe(parent);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
parent.onError(ex);
}
}
可见,把参数SubscribeOnObserver对象封装到CreateEmitter对象里,然后调用SubscribeOnObserver对象的onSubscribe(parent),通知它被订阅了。
接着继续调用ObservableCreate类对象的成员source.subscribe(parent)。前面也分析过了,source是实现ObservableOnSubscribe接口的对象。它就是我们在例子里Observable.create()的参数里的lambda表达式
Observable.create(emit -> {
Thread.sleep(5000);
emit.onNext("1");
})
看到了吧,现在终于在新线程里执行了我们的耗时操作。最后执行了emit.onNext(“1”),emit目前是CreateEmitter类对象,看一下它的onNext()
@Override
public void onNext(T t) {
if (t == null) {
onError(ExceptionHelper.createNullPointerException("onNext called with a null value."));
return;
}
if (!isDisposed()) {
observer.onNext(t);
}
}
在!isDisposed()时,会调用它的成员变量observer.onNext(t),这里observer是SubscribeOnObserver对象。再看一下它的onNext(t):
@Override
public void onNext(T t) {
downstream.onNext(t);
}
这里的downstream又是ObserveOnObserver对象。再看一下它的onNext()
@Override
public void onNext(T t) {
if (done) {
return;
}
if (sourceMode != QueueDisposable.ASYNC) {
queue.offer(t);
}
schedule();
}
ObserveOnObserver在没有经过设置的情况下,不是异步的。所以将结果存储到queue里,在这里,它是一个单一生产者单一消费者队列。接着就调用ObserveOnObserver类的schedule()
void schedule() {
if (getAndIncrement() == 0) {
worker.schedule(this);
}
}
HandlerScheduler调度,回到主线程
在这里它调用它的成员变量worker.schedule(this),不过在调用之前会先将它自身增加1(getAndIncrement()),它的worker是来自ObservableObserveOn类对象的scheduler,在例子中,它是HandlerScheduler。HandlerScheduler通过createWorker()得到HandlerWorker类型的Worker实例。看一下HandlerWorker的schedule()
@Override
@SuppressLint("NewApi") // Async will only be true when the API is available to call.
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 Disposable.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.
if (async) {
message.setAsynchronous(true);
}
handler.sendMessageDelayed(message, unit.toMillis(delay));
// Re-check disposed state for removing in case we were racing a call to dispose().
if (disposed) {
handler.removeCallbacks(scheduled);
return Disposable.disposed();
}
return scheduled;
}
这块就是Android里面的Handler消息传递了。这里封装了ScheduledRunnable,然后封装成异步消息,发送给主线程去执行,最后主线程去执行ObserveOnObserver类的run()方法。注意一下,这里又产生了线程调度。看一下ObserveOnObserver类的run():
@Override
public void run() {
if (outputFused) {
drainFused();
} else {
drainNormal();
}
}
outputFused是在请求异步处理的时候为true,目前为false。所以会执行drainNormal()。
void drainNormal() {
int missed = 1;
final SimpleQueue<T> q = queue;
final Observer<? super T> a = downstream;
for (;;) {
if (checkTerminated(done, q.isEmpty(), a)) {
return;
}
for (;;) {
boolean d = done;
T v;
try {
v = q.poll();
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
disposed = true;
upstream.dispose();
q.clear();
a.onError(ex);
worker.dispose();
return;
}
boolean empty = v == null;
if (checkTerminated(d, empty, a)) {
return;
}
if (empty) {
break;
}
a.onNext(v);
}
missed = addAndGet(-missed);
if (missed == 0) {
break;
}
}
}
我们知道,现在需要处理的结果是在queue里,现在我们就要将这个结果拿到,这里做的就是这个事情。
checkTerminated(done, q.isEmpty(), a)检查当前ObserveOnObserver的状态,是不是已经执行过dispose(),是不是已经完成。
如果状态没问题,就会取队列中结果,调用的是v = q.poll(),这样就将前面queue.offer(t)放进去的结果取出来了。如果取出来为null,也认为队列为空。这个时候,也是直接跳出循环。现在不为空,所以就执行a.onNext(v)。这个a是成员变量downstream,它在这里实际是LambdaObserver对象,调用它的onNext()。
如果我们仔细观察,会发现这块使用了两个无限循环来处理。内循环在执行了LambdaObserver对象的onNext()之后,会再次去取队列中的值,如果为空,则会调出内循环,外面的循环会增加-missed之后,结果为0,再跳出。在前面 ObserveOnObserver类的schedule()的时候,是给它自身增加了1。所以在这加上-1,即为0了。
再看一下LambdaObserver对象的onNext():
@Override
public void onNext(T t) {
if (!isDisposed()) {
try {
onNext.accept(t);
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
get().dispose();
onError(e);
}
}
}
接着就会调用LambdaObserver对象成员onNext的accept()方法。onNext是一个Consumer对象,它就是我们例子中调用subscribe()里面的参数对象,这里的参数t就是我们前面通过CreateEmitter对象的onNext(“1”)方法里的参数结果。这样就实现了在主线程中调用Consumer对象的accept(Object o)方法了。
捋完这一条完整的数据传递链条,现在应该清楚它的线程调度是怎么回事了吧。它就是通过组合封装的设计模式,实现链式调用,里面主要是线程池创建线程,还有Android的Handler传递消息机制来实现的。
ScheduledRunnable的setFuture(f)
现在我们要回到前面NewThreadWorker的scheduleActual()方法中,继续看ScheduledRunnable对象的setFuture(f)方法,这里f是线程池执行之后,返回的Future对象。
public void setFuture(Future<?> f) {
for (;;) {
Object o = get(FUTURE_INDEX);
if (o == DONE) {
return;
}
if (o == SYNC_DISPOSED) {
f.cancel(false);
return;
}
if (o == ASYNC_DISPOSED) {
f.cancel(true);
return;
}
if (compareAndSet(FUTURE_INDEX, o, f)) {
return;
}
}
}
在这里是启动了一个无限循环,会检查ScheduledRunnable对象在FUTURE_INDEX位置的值,如果为DONE,说明已经执行完毕,直接返回。如果为SYNC_DISPOSED或ASYNC_DISPOSED,这个时候,会调用参数Future对象的cancel()方法,来取消对应任务的执行,之后退出无限循环。如果值和上面的都不同,则会调用compareAndSet(FUTURE_INDEX, o, f),将FUTURE_INDEX位置设置为参数f,然后退出无限循环。
到这里基本上,把例子里面的逻辑都说通了。
主要使用了组合的设计方式,不止被观察者是这样,里面的观察者也是如此。都是一步一步先封装好,然后再一步一步拆开。其中里面有线程池的线程调度,Handler的消息机制。