Rx系列已经出来很久了,笔者也在很早就把他加入项目里使用了,具体使用方法相信大家都很熟悉了,这里就不多讲了。可是虽然用了很久,一旦过一段时间不接触就会生疏,用的时候也比较忐忑,生怕哪里会出问题。所以下决心研究一下他的源码,所谓知己知彼百战不殆。
这里就不列出使用方法了,网上资料已经很多了,也可以去官网上看。我觉得RX最核心的就是:异步以及他的操作符。本文先了解一下他的基本流程,他究竟是如何实现订阅的。
最简单最直接的方式创建一个Observable的方式如下:
Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter e) throws Exception {
e.onNext("1");
e.onComplete();
}
})
传入了一个ObservableOnSubscribe对象,我们跟进去看看
@SchedulerSupport(SchedulerSupport.NONE)
public static Observable create(ObservableOnSubscribe source) {
ObjectHelper.requireNonNull(source, "source is null");//null检查
return RxJavaPlugins.onAssembly(new ObservableCreate(source));
}
首先进行null检查,然后调用的RxJavaPlugins的onAssembly方法,他其实就是提供一个”钩子”,方便使用者进行hook,说的直白一点就是可以在调用的时候更改内部逻辑,比如这里的ObservableCreate,可以提前就设定其一定会更换为ObservableXXXX,可能你还不懂,但是没关系不影响阅读,你就当做这句代码不存在,因为正常流程并不会使用到,我会专门写一篇文章来解释RxJavaPlugins的用法。
这里我们就当做return new ObservableCreate(source),来看看这个ObservableCreate
public final class ObservableCreate<T> extends Observable<T> {
final ObservableOnSubscribe source;
public ObservableCreate(ObservableOnSubscribe source) {
this.source = source;
}
@Override
protected void subscribeActual(Observer super T> observer) {
CreateEmitter parent = new CreateEmitter(observer);
observer.onSubscribe(parent);
try {
source.subscribe(parent);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
parent.onError(ex);
}
}
//省略内部类CreateEmitter等
}
这个类也很简单,保存了我们传进来的ObservableOnSubscribe,以及subscribeActual方法,这里先卖个关子等会再来详细说这个十分重要的方法。
通常我们在最后会订阅一个observer,重写一系列方法,就像这样
//这个observable是刚刚create得来的
observable.subscribe(new Observer() {
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "onSubscribe() called with: d = [" + d + "]");
}
@Override
public void onNext(String value) {
Log.d(TAG, "onNext() called with: value = [" + value + "]");
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "onError() called with: e = [" + e + "]");
}
@Override
public void onComplete() {
Log.d(TAG, "onComplete() called");
}
});
继续跟进subscribe方法
@SchedulerSupport(SchedulerSupport.NONE)
@Override
public final void subscribe(Observer super T> observer) {
ObjectHelper.requireNonNull(observer, "observer is null");
try {
//RxJavaPlugins方法暂时不管
observer = RxJavaPlugins.onSubscribe(this, observer);
//判空
ObjectHelper.requireNonNull(observer, "Plugin returned null Observer");
//调用刚刚提到的subscribeActual
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;
}
}
可以看见subscribe方法很简单,相当于直接调用了subscribeActual方法而已,所以我们基本可以把他们画上等号:subscribe==subscribeActual,这下让我好好来看看这个subscribeActual方法
@Override
protected void subscribeActual(Observer super T> observer) {
//new了一个CreateEmitter并传入observer
CreateEmitter parent = new CreateEmitter(observer);
//调用observer的onSubscribe方法
observer.onSubscribe(parent);
try {
//这里的source就是刚才保存的ObservableOnSubscribe
source.subscribe(parent);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
parent.onError(ex);
}
}
这里才是真正干事的方法,需要注意几点
1、onSubscribe方法是和subscribeActual方法同线程调用,而不是和onNext及其他方法相同
2、最后调用了ObservableOnSubscribe的subscribe方法,也就是我们实现的方法,并传入了parent
3、parent其实就是CreateEmitter,利用装饰模式对observer进行了一些修改,下面是它的代码
static final class CreateEmitter
extends AtomicReference
implements ObservableEmitter, 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);
}
}
@Override
public void onError(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()) {
try {
observer.onError(t);
} finally {
dispose();
}
} else {
RxJavaPlugins.onError(t);
}
}
@Override
public void onComplete() {
if (!isDisposed()) {
try {
observer.onComplete();
} finally {
dispose();
}
}
}
@Override
public void setDisposable(Disposable d) {
DisposableHelper.set(this, d);
}
@Override
public void setCancellable(Cancellable c) {
setDisposable(new CancellableDisposable(c));
}
@Override
public ObservableEmitter serialize() {
return new SerializedEmitter(this);
}
@Override
public void dispose() {
DisposableHelper.dispose(this);
}
@Override
public boolean isDisposed() {
return DisposableHelper.isDisposed(get());
}
}
很明显,只是做了一些“是否被销毁或取消”的判断,真正调用的还是我们的observer的方法。
所以当我们在自己实现的subscribe方法里调用onNext时,就会调用到最下方订阅(subscribe)的observer的onNext方法,其他方法类似。
接下来我们就简单的看看一下Rx的用法,再整体理一遍流程
Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter e) throws Exception {
e.onNext("1");
e.onComplete();
}
})
.map(new Function() {
@Override
public String apply(String s) throws Exception {
return "_"+s;
}
})
.subscribe(new Observer() {
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "onSubscribe() called with: d = [" + d + "]");
}
@Override
public void onNext(String value) {
Log.d(TAG, "onNext() called with: value = [" + value + "]");
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "onError() called with: e = [" + e + "]");
}
@Override
public void onComplete() {
Log.d(TAG, "onComplete() called");
}
});
这是我们最常写的代码,利用map操作符把源头发射出来的数据做了一点修改,我这里为了简单就只是加了一个下划线。create和subscribe都看过了,这里我们来初步了解一下rxjava操作符干的事情。
@SchedulerSupport(SchedulerSupport.NONE)
public final Observable map(Function super T, ? extends R> mapper) {
ObjectHelper.requireNonNull(mapper, "mapper is null");
return RxJavaPlugins.onAssembly(new ObservableMap(this, mapper));
}
和create如出一辙,我们来看看ObservableMap的实现
public final class ObservableMap<T, U> extends AbstractObservableWithUpstream<T, U> {
final Function super T, ? extends U> function;
public ObservableMap(ObservableSource 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, function));
}
//省略内部类MapObserver
}
和create依然相同,于是我们发现了以下内容。
1、相信很多看Rxjava源码的朋友都觉得类似ObservableOnSubscribe样式的命名很乱,我起初也根本不知道是什么意思,弄得晕头转向。不过仔细观察我们发现如下规律:
Create—ObservableCreate
map—ObservableMap
切换线程的类也一样
SubscribeOn—ObservableSubscribeOn
ObserveOn—ObservableObserveOn
其实他们都是继承了Observable而已,都是实现了subscribeActual方法,并有一个自有的Observer,来装饰onNext等方法。
2、当我们调用ObservableMap的subscribeActual方法时,相当于调用source的,而source就是map上游本身,在我们的例子当中就是ObservableCreate,而ObservableCreate的subscribeActual方法我们刚刚已经分析过了,会调用我们自己实现的subscribe方法从而触发observer的方法
于是整个流程就顺利执行下来了,无论我们中间调用多少个操作符、多少的线程调度,最终都会触发到自己实现的subscribe方法从而触发observer的方法
3、ObservableMap的subscribeActual方法中调用subscribe方法传入的MapObserver包装了真正的observer,而ObservableCreate的CreateEmitter包装的就是MapObserver,所以就是
CreateEmitter–>MapObserver–>observer
这样一层层包装过的observer传给到自己实现的subscribe方法中,当然调用CreateEmitter的onNext方法就会调用MapObserver的onNext方法,所以无论中间调用多少操作符或者线程调度,最终都会调用真正的onNext方法
于是操作符就这样生效了,当然线程调度也是这样生效的,下面就通过一张图总结一下整体流程
结束了基本流程的研究,下一篇就让我们来看看线程调度的源码实现。