背景
最近在看Rxjava的相关资料, 上网搜索资料发现大部分的文章都是教授如何使用RxJava的,但是这样只知其然,不知其所以然,总是感觉学的不彻底,用着不踏实,所以就想找一些能揭示其原理的文章参考下。 But, 网上(至少是国内的网上)对于RxJava是如何实现响应式编程模式介绍文章还是比较难以找到得,不过还好,还是有大神介绍了一些原理性的文章。但是,这篇文章介绍的是基于Rxjava1的原理,目前使用的大部分已经是RxJava2了,不过,疏归同途,基本原理是一样,只不过RxJava2的实现有些差异罢了。本文通过一个例子,分析代码,梳理代码的流程,展现一下RxJava2的实现原理,权当自行学习的一个记录,也供有兴趣的同学参考。当然,RxJava2有很多使用场景和操作,这里只跟踪解析一个比较基本的例子,其他复杂的操作和使用场景,基于分析完的例子的原理可以自行扩展,参考源代码进一步分析。
分析
来看下这段代码例子
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(@NonNull ObservableEmitter<Integer> e) throws Exception {
e.onNext(1);
e.onNext(2);
e.onNext(3);
}
}).map(new Function<Integer, String>() {
@Override
public String apply(@NonNull Integer integer) throws Exception {
return "This is result " + integer;
}
}).map(new Function<String, String>() {
@Override
public String apply(@NonNull String integer) throws Exception {
return "after " + integer + " convert";
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(@NonNull String s) throws Exception {
mRxOperatorsText.append("accept : " + s +"\n");
Log.e(TAG, "accept : " + s +"\n" );
}
});
RxJava是基于观察者模式的这个大家都了解,这里我觉得RxJava这里还有一种模式的思想就是职责链模式,RxJava的响应式模式就是通过职责链的思想把对应的操作一步步链接起来的。
这里Obserable的一个操作,就对应了新建了一个的Observable类,请看代码一步步分析,以下是create操作的代码实现:
public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
ObjectHelper.requireNonNull(source, "source is null");
return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
}
这里create操作符create了一个新的ObservableCreate类,这里的ObservableCreate类继承自Observable类,主要的成员变量为
ObservableOnSubscribe<T> source;
这里就把新建的Observable类与原始的obervable也就是用户的原始数据来源(这里是emit相关的类)建立了联系:
public ObservableCreate(ObservableOnSubscribe<T> source) {
this.source = source;
}
如图:
第二步,我们来看下map操作:
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));
}
map操作的用途不用讲了,大家看过RxJava的教程应该都知道,这里我们主要来看下map操作是如何实现的。
这里的操作主要做了两件事:
- create了一个新的Obdervable类ObservableMap(为了说明 我们叫它ObservableMap1,下同)
- 然后将原来的Observable类传入,再转入Function(用户定义的映射操作)
public ObservableMap(ObservableSource<T> source, Function<? super T, ? extends U> function) {
super(source);
this.function = function;
}
然后同样的map操作,现在的关系变成了如下:
通过这些操作,我们现在就把所需要的信息都记录了下来,通过source变量形成一条信息链,为接下来的subscribe操作提供回调的线索。
接下来就是subscribe了,这里就会顺着刚才建立的关系链,一步步回调把原始的数据经过一步步的转换,传入到最后的Observer类处理。
首先来看下最初的subscribe,传入用户定义的处理类consumer (继承自Observer接口),注意这里的Observable类已经是ObservableMap2了。
所有继承了Observable的类调用的subscrib操作,疏归同途,最后都是调用Observable的subscribe操作
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;
}
}
这里subscribeActual是一个抽象方法,由其子类实现
我们来看看ObservableMap的实现
public void subscribeActual(Observer<? super U> t) {
source.subscribe(new MapObserver<T, U>(t, function));
}
这里就开始了新的关系链的建立,我们先来看看MapObserver里保存的什么
MapObserver(Observer<? super U> actual, Function<? super T, ? extends U> mapper) {
super(actual);
this.mapper = mapper;
}
原理和Observable的扩展类一样,保存了一个actual用户的执行操作 和 一个function (这里是map操作)——之前保存的用户定义的映射操作。
调用ObservableMap2.subscribe后的各个类的关系如下
参考之前的建立关系的过程,这里的source2指向的是ObservableMap1, 所以接下来调用的实际上是ObservableMap1.subscribe(MapObserver2)
OK, 那么接下来的套路跟之前一样,只不过这次到了ObservableCreate.subscribe(MapObserver1) 了
好,然后我们再来看下ObservableCreate的subscribeActual做了什么
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);
}
}
它create了一个CreateEmitter, 然后就调用source.sbuscribe(CreateEmitter )了, 好了, 这里的source就是用户定义的数据源头了
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;
}
if (!isDisposed()) {
observer.onNext(t);
}
}
最后形成的调用链就是
OK, 接下来的过程就和我们预期的一样了,看看数据是如何从源数据emit经过层层转换,到了最后用户定义的Observer的吧,拿一个onNext调用为例
ObservableEmitter.onNext() -> MapObserver1.onNext()
以上就是一个简单的RxJava应用场景的流程分析了
总结
从以上的分析可以看出,RxJava的流程主要分为两部分
- 是关系链的建立,通过Observable的source变量链接起来
- 基于建立好的关系链,建立回调关系链,回调关系链是通过Observer的actual变量链接起来的。