我们知道map操作符是Rxjava中很常见的一个操作符,它可以实现单类型转换,那么它的这个转换内部原理是怎么实现呢,我们通过源代码一步步看一下:
先写个简单的例子,例如我想实现简单的整形转字符串:
Observer endObserver = new Observer() {
@Override
public void onSubscribe(Disposable d) {
System.out.print("onSubscribe");
}
@Override
public void onNext(String s) {
System.out.print("onNext:"+s);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
};
Observable.just(200)
.map(new Function() {
@Override
public String apply(Integer integer) throws Exception {
return integer+"";
}
}).subscribe(endObserver);
为了便于理解,我们上面的写法可以拆分成这样写:
Observable observable_just = Observable.just(200);
Observable observable_map = observable_just.map(new Function(){
@Override
public String apply(Integer integer) throws Exception {
return integer+"";
}
});
observable_map.subscribe(endObserver);
}
这样我们看到有两个observable,但这两个observable是不是同一个还不知道,我们通过查看map方法的源代码看一看:
public final Observable map(Function super T, ? extends R> mapper) {
ObjectHelper.requireNonNull(mapper, "mapper is null");
return RxJavaPlugins.onAssembly(new ObservableMap(this, mapper));
}
这里看到map方法返回的是RxJavaPlugins类的onAssembly方法的返回值,而onAssembly返回的其实就是方法里传入的参数,即这里的new ObservableMap
重点:这里看到它new了一个ObservableMap,那ObservableMap又是什么呢? 其实看它继承关系就知道它继承自Observable。那么这里就能回答我们之前例子里的疑问:observable_just 和 observable_map其实不是同一个Observable,因为observable_just具体是ObservableJust,而observable_map刚才看到它是一个ObservableMap。
ObservableMap
我们看到ObservableMap的构造函数接收两个参数(this,mapper),this就是ObservableJust对象,mapper就是map方法里我们写的Function;
到这里我们知道map返回的是新创建的一个Observable,那么执行subscribe订阅操作的就是map返回的这个被观察者。那么就有问题了,这个新的被观察者去执行订阅了,我的原始被观察者observable_just怎么把数据发出去呢,什么时候发呢?下面我们通过看subscribe这个方法的代码看能不能找到里面隐藏的逻辑:
@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;
}
}
subscribe方法里面实际执行的是subscribeActual方法,而subscribeActual又是一个抽象方法,具体逻辑实在子类实现的,那么我们就得看ObservableMap的subscribeActual方法实现了:
@Override
public void subscribeActual(Observer super U> t) {
source.subscribe(new MapObserver(t, function));
}
这里看到subscribeActual方法内部是调用了source的subscribe,并且这里又new了一个MapObserver,这里我们先不管这个MapObserver是什么,后面再来分析。我们先看这个source是什么:
还记得之前map方法里new 的ObservableMap吗:
public final Observable map(Function super T, ? extends R> mapper) {
ObjectHelper.requireNonNull(mapper, "mapper is null");
return RxJavaPlugins.onAssembly(new ObservableMap(this, mapper));
}
我们再看一下ObservableMap的代码:
public final class ObservableMap extends AbstractObservableWithUpstream {
final Function super T, ? extends U> function;
public ObservableMap(ObservableSource source, Function super T, ? extends U> function) {
super(source);
this.function = function;
}
AbstractObservableWithUpstream(ObservableSource source) {
this.source = source;
}
看到这里清楚了,原来source就是我们new ObservableMap 时传的第一个参数this,即就是ObservableJust对象;
ObservableJust
那么我们是不是就应该看ObservableJust类里的subscrib方法了
public interface ObservableSource {
/**
* Subscribes the given Observer to this ObservableSource instance.
* @param observer the Observer, not null
* @throws NullPointerException if {@code observer} is null
*/
void subscribe(@NonNull Observer super T> observer);
}
发现是一个接口的方法,那我们通过看ObservableJust的类结构发现,ObservableJust时继承自Ovservable,实现了ObservableSource接口, 而Ovservable的subscribe方法实际上最终调用的是抽象方法subscribeActual,那我们就要看子类ObservableJust里的subscribeActual是怎么实现的:
private final T value;
public ObservableJust(final T value) {
this.value = value;
}
@Override
protected void subscribeActual(Observer super T> s) {
ScalarDisposable sd = new ScalarDisposable(s, value);
s.onSubscribe(sd);
sd.run();
}
这里终于看到s.onSubscribe(sd)调用了,说明从调用subscribe到订阅成功回调这套闭环走通了。那么
ScalarDisposable sd = new ScalarDisposable(s, value);
sd.run();
这两段代码又是做什么呢
ScalarDisposable
public static final class ScalarDisposable
extends AtomicInteger
implements QueueDisposable, Runnable {
看类结构发现ScalarDisposable实现了Runnable,是一个线程类,那么它的run方法里做了什么:
@Override
public void run() {
if (get() == START && compareAndSet(START, ON_NEXT)) {
observer.onNext(value);
if (get() == ON_NEXT) {
lazySet(ON_COMPLETE);
observer.onComplete();
}
}
}
看,这里调用了observer.onNext(value),说明数据就是从这里发送给观察者的。
咦,想想,这个observer是不是我们自己写那个观察者endObserver呢?
还得回到之前的ObservableMap这里看传的是什么:
@Override
public void subscribeActual(Observer super U> t) {
source.subscribe(new MapObserver(t, function));
}
这里传的是new的一个MapObserver,点进去看看MapObserver是什么,发现MapObserver实现了Observer接口,就是一个观察者,而它接收了两个参数(t,function),这个t就是我们自己写的那个endObserver:
observable_map.subscribe(endObserver);
而这个function也正是我们传给map的那个Function。
MapObserver
那么既然这两个都是我们自己传的,那MapObserver是怎么执行function以及如何发生数据给我的endObserver呢,我们看MapObserver类的代码:
static final class MapObserver extends BasicFuseableObserver {
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) {
if (done) {
return;
}
if (sourceMode != NONE) {
actual.onNext(null);
return;
}
U v;
try {
v = ObjectHelper.requireNonNull(mapper.apply(t), "The mapper function returned a null value.");
} catch (Throwable ex) {
fail(ex);
return;
}
actual.onNext(v);
}
MapObserver父类:
public BasicFuseableObserver(Observer super R> actual) {
this.actual = actual;
}
public final void onSubscribe(Disposable s) {
if (DisposableHelper.validate(this.s, s)) {
this.s = s;
if (s instanceof QueueDisposable) {
this.qs = (QueueDisposable)s;
}
if (beforeDownstream()) {
actual.onSubscribe(this);
afterDownstream();
}
}
}
看到这是不是就明白了,原来MapObserver只是对我们自己写的观察者endObserver作了一层封装,当subscribe执行到ObservableJust类的subscribeActual方法时,调用的onSubscribe和onNext都是调用的MapObserver的onSubscribe和onNext,然后MapObserver的这两个方法里有调用了endObserver的onSubscribe和onNext,同时在onNext方法里执行了我们写的Function的apply转换,然后发送数据到endObserver的onNext中。
至此,整个例子的流程算走完了,最后用一个类图总结一下整个的流程。
整个流程就是从ObservableMap的subscribe方法开始,到ObservableJust的subscribeActual,然后到MapObserver的onNext方法,这里面会执行Function的apply方法拿到转换后的数据,最后传递给endObserver的onNext方法。