分析一个Observable从创建到map到被订阅的流程,以此来明白Rxjava,是如何封住数据
如何变换数据的,从而对Rxjava有个宏观的数据改变方式的认识。以下是我们要分析的代码流程
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
em = emitter;
emitter.onNext(3);
}
}).map(new Function<Integer, String>() {
@Override
public String apply(Integer integer) throws Exception {
return String.valueOf(integer);
}
}).subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(String s) {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
先上个时序图,点击查看大图
接下来我们通过源码分析,并学习一下前辈们封装的精髓
Observable.create()方法开始
public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
ObjectHelper.requireNonNull(source, "source is null");
return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
}
创建一个ObservableCreate并返回,返回值是Observable类型。由此可见ObservableCreate一定继承了Observable。ObservableCreate的构造方法将ObservableOnSubscribe作为source变量传递过去。这里注意一下我们自己写的创建Observable类已经被传递到另一个Observable了。我们分析一下这个类。
public final class ObservableCreate<T> extends Observable<T> {
final ObservableOnSubscribe<T> source;
public ObservableCreate(ObservableOnSubscribe<T> source) {
this.source = source;
}
@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);
}
}
....
}
果然是继承Observable,同时把source作为了成员变量。subscribeActual我们放到后面调用流程里讲。
继续看我们自己写的代码,我们进行了map操作然后订阅。先简单看下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));
}
可以看见创建了一个ObservableMap返回,把自己和Function作为参数传递了过去。我们记住一点,这里传递过来一个新的Observavkle,原本的Observable已经被替换,就可以了。
继续我们自己的代码。紧接着订阅
public final void subscribe(Observer<? super T> observer) {
ObjectHelper.requireNonNull(observer, "observer is null");
try {
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;
}
}
插件代码不关心,我们分析主流程。可以看到直接调用了自己的ObservableMap(observer)这里的刚刚在分析map的时候我们说了Observable已经被替换成了ObservableMap类型的。看下subscribeActual
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));
}
}
直接调用source.suscribe(new MapObserver),注意,这里的source是我们最初创建ObservableCreate,所以这里是把observer包装成了MapObserver作为我们最初创建的ObservableCreate类subscribe方法的参数。这里有点绕,仔细想一下。接下来我们看一下如何包装的
static final class MapObserver<T, U> extends BasicFuseableObserver<T, U> {
final Function<? super T, ? extends U> mapper;
MapObserver(Observer<? super U> actual, Function<? super T, ? extends U> mapper) {
super(actual);
this.mapper = mapper;
}
@Override
public void onNext(T t) {
...
U v;
try {
v = ObjectHelper.requireNonNull(mapper.apply(t), "The mapper function returned a null value.");
} catch (Throwable ex) {
fail(ex);
return;
}
downstream.onNext(v);
}
@Override
public int requestFusion(int mode) {
return transitiveBoundaryFusion(mode);
}
@Nullable
@Override
public U poll() throws Exception {
T t = qd.poll();
return t != null ? ObjectHelper.<U>requireNonNull(mapper.apply(t), "The mapper function returned a null value.") : null;
}
}
可以看到就是先调用自己的onNext方法,拿到上游传递过来的参数时,经过mapper.apply(t),转换之后,交给下游的Observer(其实就是我们自己创建的按个observer)。接下来看一下我们就说一下,前面说放到后面讲的ObservableCreate的subscribeActual(Observer<? super T> observer)方法。这里
就很清楚了,参数传递过去的为MapObserver
@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);
}
}
实例为MapObserver的Observer被包装成到CreateEmitter里,然后回调自己的onSubscribe方法,将包装的parent传递过去,这个是为了解订阅用的,下游拿到最上游的CreateEmitter,可以dispose操作。
然后source.subscribe(parent),这个source是ObservableSubscribeOn的实例,我们知道是最初创建的时候,构造方法传递过去的。
然后经过CreateEmitter,onNext,onComplete,onError等传递事件待MapObserver经过转换后传递给我们自己的Observer,来完成我们的事件发射。到此就结束了。是不是感觉清楚了很多。
那么我们有什么可以学习的呢?我觉得收益最多的可能是代理模式的应用,其次我们清楚我们用来发射数据的Observer到底实例是不是我们写的订阅的那个Observer,在这里显然不是,而是MapObserver.它代理了我们创建的observer。数据流的处理数据,如何处理数据,Rxjava采取代理的方式来做,是非常合理而有效的。