首先来一手最简单的调用。
Observable
.create(new ObservableOnSubscribe<File[]>() {
@Override
public void subscribe(ObservableEmitter<File[]> emitter) throws Exception {
File folder = new File("xxx");
File[] files = folder.listFiles();
emitter.onNext(files);
emitter.onComplete();
}
})
.subscribe(new Observer<File[]>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(File[] files) {
//print "files"
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
在上面代码中 我获取了指定目录下的所有文件 在onNext方法收到files数组。然后 回调onComplete。
具体的实现逻辑是怎么样的呢,请看下面的分析
//Observable.create方法
public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
//判空
ObjectHelper.requireNonNull(source, "source is null");
//RxJavaPlugins.onObservableAssembly默认为空,
return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
}
Observable.create方法返回了一个ObservableCreate对象 参数是ObservableOnSubscribe。
ObservableCreate是一个继承Observable抽象类的类,同时实现了subscribeActual方法。该方法是最终调用subscribe方法开始订阅时会执行的方法。具体的实现流程都在该方法进行。
当调用完Observable.create之后 记得此时返回的类型是ObservableCreate对象
接下来是调用Observable.subscribe.
public final void subscribe(Observer<? super T> observer) {
ObjectHelper.requireNonNull(observer, "observer is null");
try {
//onObservableSubscribe默认空 ,故observer不变
observer = RxJavaPlugins.onSubscribe(this, observer);
ObjectHelper.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;
}
}
经历一系列判空之后 调用了当前bservable的subscribeActual方法 由于当前是ObservableCreate对象。查看一下他的subscribeActual方法。
protected void subscribeActual(Observer<? super T> observer) {
//observer封装进CreateEmitter
CreateEmitter<T> parent = new CreateEmitter<T>(observer);
//先回调onSubscribe
observer.onSubscribe(parent);
try {
source.subscribe(parent);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
parent.onError(ex);
}
}
CreateEmitter装饰了Observer的onNext,onComplete,onError,因为CreateEmitter实现了Disposable接口 通过CreateEmitter可以控制处理订阅是否被关闭(isDisposed(),dispose())。
source.subscribe(parent)就是调用上面的subscribe方法
public void subscribe(ObservableEmitter<File[]> emitter) throws Exception {
File folder = new File("xxx");
File[] files = folder.listFiles();
emitter.onNext(files);
emitter.onComplete();
}
在这里我回调了onNext onComplete方法。看一下这些回调方法具体做什么的
static final class CreateEmitter<T>
extends AtomicReference<Disposable>
implements ObservableEmitter<T>, Disposable {
private static final long serialVersionUID = -3434801548987643227L;
final Observer<? super T> observer;
CreateEmitter(Observer<? super T> observer) {
this.observer = observer;
}
@Override
public void onNext(T t) {
if (t == null) {
onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources."));
return;
}
//没有被关闭订阅 调用Observer的onNext
if (!isDisposed()) {
observer.onNext(t);
}
}
@Override
public void onError(Throwable t) {
if (!tryOnError(t)) {
RxJavaPlugins.onError(t);
}
}
@Override
public boolean tryOnError(Throwable t) {
if (t == null) {
t = new NullPointerException("onError called with null. Null values are generally not allowed in 2.x operators and sources.");
}
if (!isDisposed()) {
try {
observer.onError(t);
} finally {
dispose();
}
return true;
}
return false;
}
@Override
public void onComplete() {
if (!isDisposed()) {
//订阅没被关闭回调 同事关闭
try {
observer.onComplete();
} finally {
dispose();
}
}
}
@Override
public void setDisposable(Disposable d) {
DisposableHelper.set(this, d);
}
@Override
public void dispose() {
//关闭这个订阅
DisposableHelper.dispose(this);
}
@Override
public boolean isDisposed() {
//判断是否被关闭
return DisposableHelper.isDisposed(get());
}
}
由此可知 CreateEmitter就是对数据进行处理之后回调subscribe方法定义的Observer对象。
到此 一个简单的调用流程就结束了 是不是很简单。但是这样的rxjava是没有灵魂的。
rx的方便之处之一就是线程的切换。
就以上面的示例在手机上获取指定目录下的文件夹。由于这是个耗时任务 总不能在子线程执行吧。只需添加一行代码就可以很好的避免主线程耗时问题。
Observable
.create(new ObservableOnSubscribe<File[]>() {
@Override
public void subscribe(ObservableEmitter<File[]> emitter) throws Exception {
File folder = new File("xxx");
File[] files = folder.listFiles();
emitter.onNext(files);
emitter.onComplete();
}
})
//在io线程执行
.subscribeOn(Schedulers.io())
.subscribe(new Observer<File[]>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(File[] files) {
//print "files"
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
看一下subscribeOn是怎么实现的
public final Observable<T> subscribeOn(Scheduler scheduler) {
//返回一个ObservableSubscribeOn 此时返回的Observable类型对象是ObservableSubscribeOn
return RxJavaPlugins.onAssembly(new ObservableSubscribeOn<T>(this, scheduler));
}
ObservableSubscribeOn是怎么实现的呢
public final class ObservableSubscribeOn<T> extends AbstractObservableWithUpstream<T, T> {
final Scheduler scheduler;
public ObservableSubscribeOn(ObservableSource<T> source, Scheduler scheduler) {
//source是上次调用返回的ObservableSource对象
super(source);
this.scheduler = scheduler;
}
@Override
public void subscribeActual(final Observer<? super T> observer) {
//observer封装进SubscribeOnObserver
final SubscribeOnObserver<T> parent = new SubscribeOnObserver<T>(observer);
observer.onSubscribe(parent);
//通过scheduler获取相应线程执行SubscribeTask,返回disposable并且设置当前disposable
parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)));
}
static final class SubscribeOnObserver<T> extends AtomicReference<Disposable> implements Observer<T>, Disposable {
private static final long serialVersionUID = 8094547886072529208L;
final Observer<? super T> downstream;
final AtomicReference<Disposable> upstream;
SubscribeOnObserver(Observer<? super T> downstream) {
this.downstream = downstream;
this.upstream = new AtomicReference<Disposable>();
}
@Override
public void onSubscribe(Disposable d) {
DisposableHelper.setOnce(this.upstream, d);
}
@Override
public void onNext(T t) {
downstream.onNext(t);
}
@Override
public void onError(Throwable t) {
downstream.onError(t);
}
@Override
public void onComplete() {
downstream.onComplete();
}
@Override
public void dispose() {
DisposableHelper.dispose(upstream);
DisposableHelper.dispose(this);
}
@Override
public boolean isDisposed() {
return DisposableHelper.isDisposed(get());
}
void setDisposable(Disposable d) {
DisposableHelper.setOnce(this, d);
}
}
final class SubscribeTask implements Runnable {
private final SubscribeOnObserver<T> parent;
SubscribeTask(SubscribeOnObserver<T> parent) {
this.parent = parent;
}
@Override
public void run() {
source.subscribe(parent);
}
}
}
abstract class AbstractObservableWithUpstream<T, U> extends Observable<U> implements HasUpstreamObservableSource<T> {
/** The source consumable Observable. */
protected final ObservableSource<T> source;
/**
* Constructs the ObservableSource with the given consumable.
* @param source the consumable Observable
*/
AbstractObservableWithUpstream(ObservableSource<T> source) {
this.source = source;
}
@Override
public final ObservableSource<T> source() {
return source;
}
}
是不是和上面的create()方法很像 都是继承Observable实现subscribeActual方法。事实上就是通过每次的链式调用 封装不同的Observable 来递归的执行各个方法。
scheduler.scheduleDirect(new SubscribeTask(parent)暂时理解是通过scheduler创建一个线程调用SubscribeTask对象。即最终调用
source.subscribe(parent);
这里source是上一个链式调用的对象 在这里是ObservableCreate对象。parent是SubscribeOnObserver。
可以看出ObservableSubscribeOn主要功能就是根据不同的scheduler切换线程 并且继续递归调用。
总体的流程可以用下图表示:
如果我获取到文件之后要在主线程显示相关的数据,就可以这样写
Observable
.create(new ObservableOnSubscribe<File[]>() {
@Override
public void subscribe(ObservableEmitter<File[]> emitter) throws Exception {
File folder = new File("xxx");
File[] files = folder.listFiles();
emitter.onNext(files);
emitter.onComplete();
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<File[]>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(File[] files) {
//print "files" 在主线程运行
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
下面看一下 subscribe做了什么工作
public final Observable<T> observeOn(Scheduler scheduler, boolean delayError, int bufferSize) {
//相当于new ObservableSource<T>(this, scheduler, delayError, bufferSize)
return RxJavaPlugins.onAssembly(new ObservableObserveOn<T>(this, scheduler, delayError, bufferSize));
}
看一下ObservableObserveOn的subscribeActual
protected void subscribeActual(Observer<? super T> observer) {
if (scheduler instanceof TrampolineScheduler) {
source.subscribe(observer);
} else {
//获取当前Scheduler的worker 当前Scheduler是AndroidSchedulers.mainThread()
Scheduler.Worker w = scheduler.createWorker();
//调用上一个ObservableSource的订阅方法subscribe,这里例子的上一个ObservableSource对象是ObservableSubscribeOn
source.subscribe(new ObserveOnObserver<T>(observer, w, delayError, bufferSize));
}
}
由上面代码可以看出,加了observeOn和没加的区别就是加了的话新建一个ObserveOnObserver对订阅类Observer进行了封装。
那么这个ObserveOnObserver是怎么把当前observer切换到指定线程下执行的呢?
static final class ObserveOnObserver<T> extends BasicIntQueueDisposable<T>
implements Observer<T>, Runnable {
ObserveOnObserver(Observer<? super T> actual, Scheduler.Worker worker, boolean delayError, int bufferSize) {
this.downstream = actual;
this.worker = worker;
this.delayError = delayError;
this.bufferSize = bufferSize;
}
@Override
public void onSubscribe(Disposable d) {
if (DisposableHelper.validate(this.upstream, d)) {
this.upstream = d;
......
queue = new SpscLinkedArrayQueue<T>(bufferSize);
downstream.onSubscribe(this);
}
}
......
@Override
public void onNext(T t) {
if (done) {
return;
}
if (sourceMode != QueueDisposable.ASYNC) {
//把输出的值放到队列
queue.offer(t);
}
schedule();
}
@Override
public void onError(Throwable t) {
if (done) {
RxJavaPlugins.onError(t);
return;
}
//有错误不为空
error = t;
//标识完成处理
done = true;
schedule();
}
@Override
public void onComplete() {
if (done) {
return;
}
//标识完成处理
done = true;
schedule();
}
void schedule() {
if (getAndIncrement() == 0) {
//调用run()方法,这个worker是AndroidSchedulers.mainThread()生成,运行在ui线程
worker.schedule(this);
}
}
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;
}
//输出调用下游的onNext
a.onNext(v);
}
}
}
@Override
public void run() {
if (outputFused) {
drainFused();
} else {
drainNormal();
}
}
}
ObserveOnObservert通过Scheduler来完成线程的调度,上面的流程可以用下图表示:
关于Scheduler
Schedulers:存储着各种Scheduler的实例。
AndroidSchedulers:专门为Android准备的Scheduler,Scheduler下的worker运行在主线程。
所有调度器都继承Scheduler抽象类
下面以IoScheduler为例:
看一下上面的ObservableSubscribeOn.subscribeActual(final Observer<? super T> observer) ,他通过scheduler.scheduleDirect(@NonNull Runnable run)启动调度器。
该方法在基类Scheduler已经定义
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;
}
由上面可知 通过createWorker 获取Worker,然后调用schedule执行Runnable方法。
createWorker()由不同的Scheduler重写,首先看一下用的比较多的IoScheduler.
public Worker createWorker() {
return new EventLoopWorker(pool.get());
}
static final class EventLoopWorker extends Scheduler.Worker {
private final CompositeDisposable tasks;
private final CachedWorkerPool pool;
private final ThreadWorker threadWorker;
final AtomicBoolean once = new AtomicBoolean();
EventLoopWorker(CachedWorkerPool pool) {
this.pool = pool;
this.tasks = new CompositeDisposable();
this.threadWorker = pool.get();
}
@Override
public void dispose() {
if (once.compareAndSet(false, true)) {
tasks.dispose();
// releasing the pool should be the last action
pool.release(threadWorker);
}
}
@Override
public boolean isDisposed() {
return once.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;
}
return threadWorker.scheduleActual(action, delayTime, unit, tasks);
}
}
首先createWorker() 方法直接返回了EventLoopWorker对象 他有一个参数是CachedWorkerPool类型。
CachedWorkerPool的作用是从队列获取worker和回收worker。
当初始化EventLoopWorker的时候,从CachedWorkerPool拿一个worker保存。
CachedWorkerPool是怎么拿的呢?
ThreadWorker get() {
if (allWorkers.isDisposed()) {
return SHUTDOWN_THREAD_WORKER;
}
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;
}
他会首先从expiringWorkerQueue查询 如果有就直接返回 如果没有就新建一个ThreadWorker 返回。
所以EventLoopWorker.schedule实际上是执行了ThreadWorker.scheduleActual
//ThreadWorker.scheduleActual
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;
}
由此就知道了 最终的Runnable就到线程池下执行了。
最终 总结一下各种Scheduler:
Schedulers.IO:可以无限创建worker执行 每个worker绑定一个线程,当worker执行完毕或者dispose()之后,会保存进缓存队列一段时间等待重用。
Schedulers.SINGLE:只在一个线程上执行。
Schedulers.COMPUTATION:一开始直接创建默认是cpu个数的worker 每次调度都会轮流获取worker调度。
Schedulers.NEW_THREAD:每次都是直接创建一个新worker执行。
Schedulers.TRAMPOLINE: 直接在当前线程执行 ,不过是先放到一个阻塞队列,然后在从队列取出来执行
AndroidSchedulers.mainThread():在ui线程执行worker
上述的创建worker 都是继承自NewThreadWorker 他在初始化的时候会创建线程池。
public NewThreadWorker(ThreadFactory threadFactory) {
executor = SchedulerPoolFactory.create(threadFactory);
}
public static ScheduledExecutorService create(ThreadFactory factory) {
final ScheduledExecutorService exec = Executors.newScheduledThreadPool(1, factory);
tryPutIntoPool(PURGE_ENABLED, exec);
return exec;
}
如上 创建一个单线程的ScheduledExecutorService。
本文基于rxjava2.2.8 。
水平有限如有错误欢迎指正