再看 RxJava 之前,我们需要先了解一下在 RxJava 中的角色
ObservableSource 被观察者
Observer 观察者
Emitter 发射器
下面我们就从一个最简单的例子开始解读RxJava 的工作流程
kotlin
var obs= Observable.create(object :ObservableOnSubscribe<String> {
override fun subscribe(e: ObservableEmitter<String>?) {
e?.onNext("1")
}
})
obs.subscribe {
}
为了让所有人都能看明白代码的加载顺序与执行顺序,这里没有采用链式调用的方法,而是创建变量来操作的,
我们先来 Observable.create 都干了什么
csharp
public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
ObjectHelper.requireNonNull(source, "source is null");
return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
}
这里的代码异常的简单, 先来说一下 RxJavaPlugins.onAssembly 干了点啥,
typescript
public static <T> Observable<T> onAssembly(Observable<T> source) {
Function<Observable, Observable> f = onObservableAssembly;
if (f != null) {
return apply(f, source);
}
return source;
}
static <T, R> R apply(Function<T, R> f, T t) {
try {
return f.apply(t);
} catch (Throwable ex) {
throw ExceptionHelper.wrapOrThrow(ex);
}
}
public static void setOnObservableAssembly(Function<Observable, Observable> onObservableAssembly) {
if (lockdown) {
throw new IllegalStateException("Plugins can't be changed anymore");
}
RxJavaPlugins.onObservableAssembly = onObservableAssembly;
}
onObservableAssembly 这个变量是RxJava 全局的静态变量,他能让我们看到每一次转换过程中都经历了什么,相当于一个后门,不过没见过哪里用到了这个,只能看修改会出现问题,并且从这里获取的信息比较有限,但是他确实是一个我们用的后门,
如果没有设置 RxJavaPlugins.onAssembly ,那么 只需要关心 new ObservableCreate(source)这段代码了
scala
public final class ObservableCreate<T> extends Observable<T> {
final ObservableOnSubscribe<T> source;
public ObservableCreate(ObservableOnSubscribe<T> source) {
this.source = source;
}
}
这段代码就是将我们 create 方法创建的 这个 ObservableOnSubscribe 持有一下,
kotlin
object :ObservableOnSubscribe<String> {
override fun subscribe(e: ObservableEmitter<String>?) {
e?.onNext("1")
}
}
我们继续来分析 obs.subscribe { } 这段代码都干了什么,这个方法最终会流向 RxJava 中的 如下方法
java
@SchedulerSupport(SchedulerSupport.NONE)
@Override
public final void subscribe(Observer<? super T> observer) {
ObjectHelper.requireNonNull(observer, "observer is null");
try {
observer = RxJavaPlugins.onSubscribe(this, observer);
ObjectHelper.requireNonNull(observer, "Plugin returned null Observer");
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;
}
}
observer = RxJavaPlugins.onSubscribe(this, observer); 这个方法同样是后门方法,这里就不分析了,然后就调用了 subscribeActual(observer); 这个方法 , 首先要清楚是谁调用的subscribe 方法,没错就是 ObservableCreate 这个类, 我们去看一下 ObservableCreate 他的 subscribeActual(observer) 方法
typescript
@Override
protected void subscribeActual(Observer<? super T> observer) {
CreateEmitter<T> parent = new CreateEmitter<T>(observer);
observer.onSubscribe(parent);
try {
source.subscribe(parent);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
parent.onError(ex);
}
}
首先是先组装了一下 CreateEmitter 用来发射用的 ,然后马上就调用了 observer.onSubscribe 这个回调,所以每次必然都是 onSubscribe 这个方法第一个回调 , 然后就调到了我们在create 的时候传入的回调,而我们在create 的时候调用的是 Emitter 的noNext 方法 ,那么我们先来看看 CreateEmitter 的next 干了啥
typescript
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;
}
if (!isDisposed()) {
observer.onNext(t);
}
}
可以看到 onNext 直接调用的 subscribe 传入的 Observe 的 onNext 回调,整个流程就分析完成了,但是只看一个create 的操作符是感受不到Rxjava 的伟大之处的,但是又为什么将只有一个create 就 调用 subscribe 的拿出来说呢,主要目的是为了先让大家对于他的流程有个大概的理解,加入更多操作符后理解起来更加的轻松
在加入更多的操作符前,只通过一个create我们能看到什么,
RxJava 是一个冷流,只有在 subscribe 调用才才会触发上游开始发送事件,再仔细体会一下是不是这个道理
crate map subscribe
先上例子
kotlin
Observable.create(object : ObservableOnSubscribe<Int> {
override fun subscribe(e: ObservableEmitter<Int>) {
e.onNext(1)
}
}).map {
return@map "变换后的$it"
}.subscribe {
Log.i("tian.shm", "$it")
}
这里还是先创建 ObservableCreate
scala
public final class ObservableCreate<T> extends Observable<T> {
final ObservableOnSubscribe<T> source;
public ObservableCreate(ObservableOnSubscribe<T> source) {
this.source = source;
}
}
然后调用 ObservableCreate.map 变化
less
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
public final <R> Observable<R> map(Function<? super T, ? extends R> mapper) {
ObjectHelper.requireNonNull(mapper, "mapper is null");
return RxJavaPlugins.onAssembly(new ObservableMap<T, R>(this, mapper));
}
仔细看这里使用的 ObservableCreate 的 又创建了一个 ObservableMap,注意在创建ObservableMap的时候使用的this,也就是在create操作符创建的 ObservableCreate, 我们再先来看看
typescript
public final class ObservableMap<T, U> extends AbstractObservableWithUpstream<T, U> {
final Function<? super T, ? extends U> function;
public ObservableMap(ObservableSource<T> source, Function<? super T, ? extends U> function) {
super(source);
this.function = function;
}
@Override
public void subscribeActual(Observer<? super U> t) {
source.subscribe(new MapObserver<T, U>(t, function));
}
}
Map 操作符的创建也是平平无奇
但是这里需要画一个图来标识我们创建的关系
在我们使用了create 与 map 操作符后,形成的包裹关系就变成了这个样子,代码在没有调用到 subscribe 之前是一层一层包裹起来的,
当我们调用 subscribe 方法后就相当于我们调用了 ObservableMap 的 subscribeActual方法,我们先来看一下代码,
typescript
@Override
public void subscribeActual(Observer<? super U> t) {
source.subscribe(new MapObserver<T, U>(t, function));
}
可以看到 这里有调用到了 ObservableCreate 的 subscribeActual 的方法里面,使用Map 的监听将 subscribe 的监听包裹一下,那么上层的 ObservableCreate 他的观察者就是 MapObserve,这样 MapObserve 就可以转换数据了,
整个过程使用图片就变成了下面这个样子
看了这张图片后整个流程瞬间就清晰多了,这个里面有点绕,大家可以配合这源码再自己分析一下这个流程
crate map1 subscribeOn map2 observeOn map3 subscribe
其实这个流程主要是想介绍一下 subscribeOn 与 observeOn ,以及为什么他们能做到线程调度,并且说明一下他们的都能调度那个阶段的代码
了解了上面的包裹的这个过程,这里我们就能直接看一下
scala
public final class ObservableSubscribeOn<T> extends AbstractObservableWithUpstream<T, T> {
final Scheduler scheduler;
public ObservableSubscribeOn(ObservableSource<T> source, Scheduler scheduler) {
super(source);
this.scheduler = scheduler;
}
@Override
public void subscribeActual(final Observer<? super T> s) {
final SubscribeOnObserver<T> parent = new SubscribeOnObserver<T>(s);
s.onSubscribe(parent);
parent.setDisposable(scheduler.scheduleDirect(new Runnable() {
@Override
public void run() {
source.subscribe(parent);
}
}));
}
}
从代码的逻辑可以看出来,在使用 ObservableSubscribeOn 包裹后, 使用 subscribe 订阅后,执行到 ObservableSubscribeOn 后,会使用 scheduler 将包裹内的继续向上查找的线程改变了,而且也将发射的线程也改变了,看到网上很多人都说 subscribeOn 只能改变上层的线程,其实这里是不对的,如果没有调度指令的话,除了在 subscribe 过程中 包裹 ObservableSubscribeOn 的线程没有改变,所有的线程都被改变了,为了证明这个结论创建了下面的例子
kotlin
Observable.create(ObservableOnSubscribe<String> {
Log.i("tian.shm","create Thread Name:${Thread.currentThread().name}")
it.onNext("1")
}) .map {
Log.i("tian.shm","map1 Thread Name:${Thread.currentThread().name}")
return@map it
}.subscribeOn(Schedulers.io())
.map {
Log.i("tian.shm","map2 Thread Name:${Thread.currentThread().name}")
return@map it
}
.observeOn(AndroidSchedulers.mainThread())
.map {
Log.i("tian.shm","map3 Thread Name:${Thread.currentThread().name}")
return@map it
}
.subscribe {
Log.i("tian.shm","Thread Name:${Thread.currentThread().name}")
}
结果如下
ruby
: create Thread Name:RxCachedThreadScheduler-1
: map1 Thread Name:RxCachedThreadScheduler-1
: map2 Thread Name:RxCachedThreadScheduler-1
: map3 Thread Name:main
: Thread Name:main
看完了 subscribeOn 是在向上查找过程中改变了线程,那么 observeOn 这个就非常容易想到他是在哪里改变的线程
java
public final class ObservableObserveOn<T> extends AbstractObservableWithUpstream<T, T> {
final Scheduler scheduler;
final boolean delayError;
final int bufferSize;
public ObservableObserveOn(ObservableSource<T> source, Scheduler scheduler, boolean delayError, int bufferSize) {
super(source);
this.scheduler = scheduler;
this.delayError = delayError;
this.bufferSize = bufferSize;
}
@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<T>(observer, w, delayError, bufferSize));
}
}
}
在 ObservableObserveOn 这个类中,他将 Scheduler.Worker 这个worker 传入了 ObserveOnObserver 中了,没错,他就是在 ObserveOnObserver 中改变结果的监听的
scss
@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);
}
}
可以看到确实是这个样子的, observeOn改变的是发射数据后,执行Observe过程中的线程, 到了这里整个RxJava 的简单分析就完成了