接触RxJava
算是比较早了,早期RxJava 1.0
出来的时候就结合Retrofit
然后搭配MVP框架使用了, 年初加入新公司也有用到RxJava
不过中间比较长一段时间没有接触,准备彻底深入的学习一下。
首先,先来看一段代码:
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
e.onNext("1");
e.onNext("2");
e.onNext("3");
e.onComplete();
e.onNext("4");
}
}).subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
Log.w("Jayuchou", "=== onSubscribe === ");
}
@Override
public void onNext(String s) {
Log.w("Jayuchou", "=== onNext === " + s);
}
@Override
public void onError(Throwable e) {
Log.w("Jayuchou", "=== onError === ");
}
@Override
public void onComplete() {
Log.w("Jayuchou", "=== onComplete === ");
}
});
代码跑起来很自然的输出了一些数据出来,从logcat复制粘贴看看一下:
com.neacy.rxjava W/Jayuchou: === onSubscribe ===
com.neacy.rxjava W/Jayuchou: === onNext === 1
com.neacy.rxjava W/Jayuchou: === onNext === 2
com.neacy.rxjava W/Jayuchou: === onNext === 3
com.neacy.rxjava W/Jayuchou: === onComplete ===
为什么e.onNext("4")
这个没有输出呢,毕竟这么简单的一段代码肯定不会写错的,所以很有必要看看里面做了什么猫腻,这就是本篇文章所想表达的意图。
源码分析
我们从Observable.create
声明开始看起,左手键盘右手鼠标轻轻一点:
public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
ObjectHelper.requireNonNull(source, "source is null");
return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
}
这里面的RxJavaPlugins.onAssembly
返回的就是ObservableCreate
所以我们进入ObservableCreate
类看看里面做了什么操作:
public final class ObservableCreate<T> extends Observable<T> {
final ObservableOnSubscribe<T> source;
public ObservableCreate(ObservableOnSubscribe<T> source) {
this.source = source;
}
}
好像这么一步的操作也没有什么非常神奇的操作,只是把我们new出来的ObservableOnSubscribe
赋值给他的成员变量source
,看过去声明过程并不是很复杂很麻烦的相对还是比较清晰。
那么我们看下subscribe
之后发生了什么:
public final void subscribe(Observer<? super T> observer) {
// 删除一些无关代码
try {
observer = RxJavaPlugins.onSubscribe(this, observer);
subscribeActual(observer);
}
// 删除一些无关代码
...
}
RxJavaPlugins.onSubscribe
返回的是我们传入的Observer
对象用于接收onNext等操作的传递出来的数据。主要是subscribeActual
这个方法,但是在Observable
中这个方法是个abstract
抽象方法,所以我们找到了ObservableCreate
中的相对应的方法:
@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);
}
}
一旦看到陌生的类我们就自然的点进去看看内部做了哪些操作,就比如CreateEmitter
这个陌生的类。而这个类implements ObservableEmitter
所以我们自然就找到了我们一直想要看的方法:
public interface Emitter<T> {
void onNext(@NonNull T value);
void onError(@NonNull Throwable error);
void onComplete();
}
我们再回头看一下subscribeActual
这个方法,声明完CreateEmitter
对象之后就直接执行了:
observer.onSubscribe(parent);
//执行完上面的方法会在AS的logCat输出如下的日志:
com.neacy.rxjava W/Jayuchou: === onSubscribe ===
这样子我们就明白了Observer.onSubscribe
这个方法是一执行subscribe
之后就会开始被调用了。
这时候方法就会继续执行下去,就会执行:
source.subscribe(parent);
这段代码很有意思就是直接代理调用我们在Activity
中声明:
public void subscribe(ObservableEmitter<String> e) throws Exception {
e.onNext("1");
e.onNext("2");
e.onNext("3");
e.onComplete();
e.onNext("4");
}
Ok,知道了什么时候会开始输出数据了,仿佛就流程就走的差不多了。但是,并不是这样的我们要看下具体每个方法做了什么为什么最后一个onNext
没有输出呢?
onNext:
@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);
}
}
看了一眼就会后悔,早知道不看了,确实onNext
没有做什么操作直接通过observer
把数据输出来,当然有稍微判断一下是否这个Observable是disposed。
onComplete:
public void onComplete() {
if (!isDisposed()) {
try {
observer.onComplete();
} finally {
dispose();
}
}
}
其实onComplete
的判断也是比较简单,不过我们要当心finally
中的代码执行了dispose
:
public void dispose() {
DisposableHelper.dispose(this);
}
// DisposableHelper类:
public static boolean dispose(AtomicReference<Disposable> field) {
Disposable current = field.get();
Disposable d = DISPOSED;
if (current != d) {
// 把当前的Disposable赋值成DISPOSED 也就是说isDisposed = true
current = field.getAndSet(d);
if (current != d) {
if (current != null) {
current.dispose();
}
return true;
}
}
return false;
}
所以很清楚了最后isDisposed = true
这样子在onNext
的时候不是会判断!isDisposed()
这里就会返回false那么久无法再次执行onNext
所以说这就是为什么执行了onComplete
之后就不会再次执行onNext
的原因了。
这时候你再看一眼onError
你会发现跟onComplete
是一样的原理。
总结:一旦执行了onComplete
或者onError
之后就不会再次执行onNext
了。