一 前言
Rxjava最好用的其实还是它的变换操作符,接下来我们来剖析一下常用的变换操作符的实现原理;操作符的分析我打算是分成两篇学习,先从简单的map入手,当了解其本质后再分析强大的flatMap操作符。
二 从Demo到源码
我们先来看一个例子:
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> e) throws Exception {
e.onNext(1);
e.onNext(2);
e.onNext(3);
}
}).map(new Function<Integer, String>() {
@Override
public String apply(Integer integer) throws Exception {
return integer + "a";
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.d("map:",s);
}
});
=================================================
结果:
2021-02-02 11:08:00.782 11974-11974/com.example.myapplication D/map:: 1a
2021-02-02 11:08:00.782 11974-11974/com.example.myapplication D/map:: 2a
2021-02-02 11:08:00.782 11974-11974/com.example.myapplication D/map:: 3a
当然,操作符map提供的能力肯定不止这样,你可以的apply回调里面编写需要的逻辑代码。
三 源码分析
我们先从map这个方法入手,看看内部到底做了什么:
Class Obserable{
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));
}
}
果然,还是熟悉的代码,变得只有onAssembly参数里面的东西,这里可以注意一下:T为上游Observable下发的数据类型,R为下游Observer将要接收的数据类型,也就是说,暂时我们可以这样理解,T转换为R,为什么这样说呢,因为到flatMap时,就不能这样简单的理解了。
我们继续来看ObservableMap这个类,看看它的继承结构:
还是老套路了,包装传入的source(被观察者Observable)之后返回。现在来看看ObservableMap里面的具体实现:
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) {
//1、source 为上游的Observable
super(source);
//2、 function 为我们传入的funcation对象
this.function = function;
}
@Override
public void subscribeActual(Observer<? super U> t) {
//3、t为下游的Observer对象
source.subscribe(new MapObserver<T, U>(t, function));
}
static final class MapObserver<T, U> extends BasicFuseableObserver<T, U> {
final Functionsuper T, ? extends U> mapper;
MapObserver(Observer<? super U> actual, Functionsuper T, ? extends U> mapper) {
//4、actual 为下游的Observer
super(actual);
//5、mapper为我们传入的function函数对象
this.mapper = mapper;
}
@Override
public void onNext(T t) {
if (done) {
return;
}
...
U v;
try {
//6、调用mapper的apply方法,或者apply回调的返回值
v = ObjectHelper.requireNonNull(mapper.apply(t), "The mapper function returned a null value.");
} catch (Throwable ex) {
fail(ex);
return;
}
//7、回调下游Obsever的onNext方法
actual.onNext(v);
}
.....
}
}
map方法返回的Observable包装类ObservableMap被下游的Observer所定阅,出发了ObservableMap里的subscribeActual方法,此方法则是下游Observer的包装类MapObserver订阅了上游Observable,Observable下发数据,MapObserver这个包装类只是媒介,通过下游Observer引用t,实现了下游Observer对上游Observable下发事件的接收。
第六点这里就调用了demo里function中重写的方法apply()方法,通过返回值实现了不同类型的转换接着作为参数回调下游Observer的onNext方法,最终实现了转换的目的。
这里大家会奇怪,怎么少了onError,onCompeter,以及onSubscribe方法呢?可能这些实现在MapObserver的父类BasicFuseableObserver:
public abstract class BasicFuseableObserver<T, R> implements Observer<T>, QueueDisposable<R> {
...
public BasicFuseableObserver(Observersuper R> actual) {
this.actual = actual;
}
@SuppressWarnings("unchecked")
@Override
public final void onSubscribe(Disposable s) {
if (DisposableHelper.validate(this.s, s)) {
//1、接收下游的Disposable加入管理队列
this.s = s;
if (s instanceof QueueDisposable) {
this.qs = (QueueDisposable<T>)s;
}
//2、可以重写onSubscribe()的回调之前做一些操作
if (beforeDownstream()) {
actual.onSubscribe(this);
//3、可重写在onSubscribe调用后做一些操作
afterDownstream();
}
}
}
@Override
public void onError(Throwable t) {
if (done) {
RxJavaPlugins.onError(t);
return;
}
done = true;
actual.onError(t);
}
@Override
public void onComplete() {
if (done) {
return;
}
done = true;
actual.onComplete();
}
...
}
果然,为了简化子类代码,这里对公共的方法抽取到了父类里实现了。
四 总结
Ok,根据上面的分析,其实对于map的操作过程我们已经很清楚了,其跟之前的线程切换的实现原理基本一样,通过在中间使用装饰者模式插入一个中间的Observable和Observe,你可以想象为代理。
代理Observable做的事就是接收下游Obsever的订阅事件,然后通过代理Obsever订阅上游Observer,然后在上游Observer下发数据給代理Observer时,通过先调用mapper.apply转换回调函数获得转换后的数据,然后下发给下游Obsever。
Ok,其实就是这样,在RxJava2中大量运用装饰者模式来实现扩展功能。
RxJava2的flatMap高级转换函数我们将再下篇进行分析。