最近复习RxJava的时候发现解说RxJava的原理不多,所以,来机智的骗心心来了。
依赖:
implementation "io.reactivex.rxjava2:rxjava:2.2.4"
简单使用
待会儿讲解的原理呢,是由这个使用 demo 来讲解。
Observable.create(new ObservableOnSubscribe() { // 创建被观察者
@Override
public void subscribe(ObservableEmitter emitter) throws Exception {
emitter.onNext(1); // 发射器,发射一个事件
emitter.onNext(2);
}
}).subscribe(new Consumer() { // 观察者
@Override
public void accept(Integer integer) throws Exception { // 用于处理 onNext 事件
Log.d(TAG, "accept: "+integer);
}
}, new Consumer() {
@Override
public void accept(Throwable throwable) throws Exception {
Log.d(TAG, "accept: "+throwable.getMessage());
}
});
原理解析
Observable.create(ObservableOnSubscribe)
在上面的使用demo中,这是整个订阅过程的开始:创建一个被观察者。来,我们看一下我们的被观察者是什么。
Observable.class
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
public static Observable create(ObservableOnSubscribe source) {
ObjectHelper.requireNonNull(source, "source is null"); // 判空
return RxJavaPlugins.onAssembly(new ObservableCreate(source)); // 默认直接返回这个new出来的ObservableCreate
}
这个ObjectHelper.requireNonNull
怎么判空啊?
public static T requireNonNull(T object, String message) {
if (object == null) {
throw new NullPointerException(message);
}
return object;
}
简直不要太简单,就是判断输入的object是不是null,不是就返回,是就抛出异常。
那这个RxJavaPlugins
又是干嘛的呢?用过的都知道,没用过推荐看一下给初学者的RxJava2.0教程(十) 。其实我们没有对这个 RxJavaPlugins 做设置的话,就是返回我们传进来的这个参数。后面我们看到这个RxJavaPlugins就可以默认为直接返回参数。
书接上文,那调用 Observable.create(ObservableOnSubscribe)
,岂不是就是把自己在外部实现的 ObservableOnSubscribe 匿名内部类包装到 ObservableCreate
中去罗。
public final class ObservableCreate extends Observable { // 注意继承关系哦
final ObservableOnSubscribe source; // 最原始的目标:被观察者
public ObservableCreate(ObservableOnSubscribe source) {
this.source = source; // 传进来的是外面new的匿名内部类ObservableOnSubscribe
}
...
}
看到这里,emmm,nice,保存住了被观察者,返回了ObservableCreate
对象。注意哦,这个时候后面一个 .
操作的就是这个 ObservableCreate
对象(换言之,后面点的就是ObservableCreate
中的方法)。
好的,下面就是 .subscribe
.subscribe
这个方法就很有意思了,实现了订阅这个操作,或者说,是触发了onSuscribe、onNext 等操作。
先看一下 subscribe 这个方法的重载:
public final Disposable subscribe() {} // 注意哦,这里的都是final方法
public final Disposable subscribe(Consumer super T> onNext) {}
public final Disposable subscribe(Consumer super T> onNext, Consumer super Throwable> onError) {}
public final Disposable subscribe(Consumer super T> onNext, Consumer super Throwable> onError, Action onComplete) {}
public final Disposable subscribe(Consumer super T> onNext, Consumer super Throwable> onError, Action onComplete, Consumer super Disposable> onSubscribe) {}
public final void subscribe(Observer super T> observer) {}
有点多哈,但是实现呢?很简单,大家都调用最后一个处理,没有传参的都添上默认的 Custom 就可以了。什么叫默认实现,就是实现了接口,但是默认不处理,比如默认的Action,还有就是简单处理,比如onError,但是都不是很重要,我们主要关注我们自己实现的东西嘛。
public final Disposable subscribe(Consumer super T> onNext, Consumer super Throwable> onError) {
return subscribe(onNext, onError, Functions.EMPTY_ACTION, Functions.emptyConsumer());
}
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
public final Disposable subscribe(Consumer super T> onNext, Consumer super Throwable> onError,
Action onComplete, Consumer super Disposable> onSubscribe) {
ObjectHelper.requireNonNull(onNext, "onNext is null"); // 挨个判空
ObjectHelper.requireNonNull(onError, "onError is null");
ObjectHelper.requireNonNull(onComplete, "onComplete is null");
ObjectHelper.requireNonNull(onSubscribe, "onSubscribe is null");
LambdaObserver ls = new LambdaObserver(onNext, onError, onComplete, onSubscribe); // 用一个类来包裹
subscribe(ls); // 包裹类的订阅
return ls;
}
那么这个用来包裹的 LambdaObserver 又是什么鬼呢?
public final class LambdaObserver extends AtomicReference
implements Observer, Disposable, LambdaConsumerIntrospection {
private static final long serialVersionUID = -7251123623727029452L;
final Consumer super T> onNext;
final Consumer super Throwable> onError;
final Action onComplete;
final Consumer super Disposable> onSubscribe;
public LambdaObserver(Consumer super T> onNext, Consumer super Throwable> onError,
Action onComplete,
Consumer super Disposable> onSubscribe) {
super();
this.onNext = onNext;
this.onError = onError;
this.onComplete = onComplete;
this.onSubscribe = onSubscribe;
}
...
}
就是将四个类型(onNext,onError,onComplete,onSubscribe)封装成一个一个对象,方便对整个流程的调用。
将四个对象封装在一起了过后,就是应该是订阅了把?
@SchedulerSupport(SchedulerSupport.NONE)
@Override
public final void subscribe(Observer super T> observer) {
ObjectHelper.requireNonNull(observer, "observer is null");
try {
observer = RxJavaPlugins.onSubscribe(this, observer); // 检查需要执行预操作不,默认返回 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); // 错误的话,捕获,并交给RxJavaPlugins#onError来处理,没有交给我们自定义的onError,莫看错啦
NullPointerException npe = new NullPointerException("Actually not, but can't throw other exceptions due to RS");
npe.initCause(e);
throw npe;
}
}
真正有用的就是 subscribeActual(observer);
这一句,吐血哦,还不订阅,我都快等不及了。好嘛,大神就是大神,一看,自己没实现。后面一想,就是牛逼。
/**
* Operator implementations (both source and intermediate) should implement this method that
* performs the necessary business logic and handles the incoming {@link Observer}s.
* There is no need to call any of the plugin hooks on the current {@code Observable} instance or
* the {@code Observer}; all hooks and basic safeguards have been
* applied by {@link #subscribe(Observer)} before this method gets called.
* @param observer the incoming Observer, never null
*/
protected abstract void subscribeActual(Observer super T> observer);
所有的操作符都会重写这个方法,我是不是暴露了什么,emm,所有运算符返回都是 Observable 的子类,就比如说 create
返回的就是 Observable
的子类 ObservableCreate
,后面就是在这基础上调用了。这里我们可以看到,其实所有的 subscribe 我们都重写不了,唯一能重写且必须重写的就是这个 subscribeActual。这就意味着,这个方法是我子类实现真正订阅的入口。
前面讲解我们知道,现在在demo中调用的是 ObservableCreate 的 subscribe,那么事情就变得很简单,我们直接找到 ObservableCreate#subscribeActual(observer) 进行分析就好。在分析之前,先用图总结下前面的东西:
好的嘞,那我们接下来就看一下核心的 subscribeActual 方法如何实现的?
@Override
protected void subscribeActual(Observer super T> observer) { //传进来的就是前面的 LambdaObserver
CreateEmitter parent = new CreateEmitter(observer); // 发射器,每一个操作符对应的类内部都会自己实现,因为处理逻辑不一样啊
observer.onSubscribe(parent); // 回调了自己实现的 onSubscribe 对用的Consumer
try {
source.subscribe(parent); // 这个source就是初始化类的时候传进来的被观察者,这里将发送器给了它
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
parent.onError(ex); // 这里捕获的异常才交给自己写的Consumer处理
}
}
这里代码不多,干的事还不少,首先是new出我们的发射器,然后触发被观察者的订阅回调,然后再,执行被观察者的subscribe方法,如果捕获到异常就交给自定义的 onError 处理。
有一个概念可以先了解,无论以后把这个对象怎么包裹,传递,只有这里才调用了被观察者 Observable 的 subscribe
方法。
接下来我们来详解一下,这个回调流程。
observer.onSubscribe(parent);
这里的 observer 是什么?传进来的 包装有自定义的观察者的 LambdaObserver ,他是 Observable 的子类。接下来看一下他的调用:
@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); // 并向下传递
}
}
}
@Override
public void onError(Throwable t) {
if (!isDisposed()) { // 判断是否断开连接
lazySet(DisposableHelper.DISPOSED);
try {
onError.accept(t); //交给自定义的消费者
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
RxJavaPlugins.onError(new CompositeException(t, e));
}
} else {
RxJavaPlugins.onError(t);
}
}
很简单,对不对,就是直接调用了 onNext 消费者的 accept 方法(自定义或者默认)。出现异常,如果没有断开连接,且是第一次接收到,就交给 onError (自定义或者默认)处理。
那么 source.subscribe(parent);
不会也这么简单把?
source 就是传进来的 ObservableOnSubscribe,自定义的被观察者
parent 就是发射器。这一调用,我们自己写的被观察者的逻辑就巴拉巴拉的执行了
这里就是直接就回调了。吓人。。
那 parent.onError(ex);
怎么实现的?这就要真正说道说道这个发射器了。
发送器是什么狗东西呢?它是ObservableCreate
的静态内部类:
static final class CreateEmitter extends AtomicReference implements ObservableEmitter, Disposable {
final Observer super T> observer; // 观察者,就是传进来的 LambdaObserver
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); // 调用自定义的Custom回调处理
}
}
@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()) { //没断开,不为null
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()); }
}
咦,这结构简直不要太简单,就相当于一次中转,只不过是加入了一些容错机制。到这里整个流程要用到的类就结束了,当我们在书写被观察者的时候,使用这个发射器提交东西,就是直接调用这个东西来调用消费者的对应回调。
千言不如一图
不对,放错了
- 创建真正的被观察者包裹对象(继承于 Observable),并将自己写的真正被观察者包裹起来
- 调用被观察者的subscribe方法,将自己创建的观察者包裹起来
- 作为参数,传入ObservableCreate 对方实现的 subscribeActual(Observer) 中。
- 在 subscribeActual 方法中生成 emitter,并且回调被观察者的onSubscribe,确定连接关系。
- 自己写的被观察者的 subscribe 调用,我们可以使用 emitter 提交东西,一提交就将提交的东西交给 被观察者对应的方法执行