概述:
從最簡單的RxJava的使用,來分析RxJava訂閱和觀察的整個流程(注:RxJava版本:2.2.7)
目標:
- RxJava中觀察者和被觀察者是如何聯繫起來的
- 被觀察者(Observable)發射數據是從什麼時候開始的,
- Observable的整個流程圖
分析
最簡單的RxJava代碼如下:下面代碼實現了 被觀察者,發射一個1,觀察者得到該發射的值並打印出來
Observable.create(new ObservableOnSubscribe<Object>() {
@Override
public void subscribe(ObservableEmitter<Object> emitter) throws Exception {
emitter.onNext(1);
emitter.onComplete();
}
}).subscribe(new Observer<Object>() {
@Override
public void onSubscribe(Disposable d) {
Log.d("RxJava:", "onSubscribe");
}
@Override
public void onNext(Object o) {
Log.d("RxJava:", "onNext"+o.toString());
}
@Override
public void onError(Throwable e) {
Log.d("RxJava:", "onError");
}
@Override
public void onComplete() {
Log.d("RxJava:", "onComplete");
}
});
運行結果:
2020-01-07 10:33:46.888 7381-7381/com.wkkun.litho D/RxJava:: onSubscribe
2020-01-07 10:33:46.888 7381-7381/com.wkkun.litho D/RxJava:: onNext1
2020-01-07 10:33:46.888 7381-7381/com.wkkun.litho D/RxJava:: onComplete
我們首先查看 Observable.create()方法,如下:
public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
//判斷是否爲空,如果爲null 則拋出異常
ObjectHelper.requireNonNull(source, "source is null");
return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
}
RxJavaPlugins.onAssembly() 方法
/**
* Calls the associated hook function. 調用關聯的hook方法
* @param <T> the value type
* @param source the hook's input value hook的輸入值
* @return the value returned by the hook hook的返回值
*/
@NonNull
public static <T> Observable<T> onAssembly(@NonNull Observable<T> source) {
Function<? super Observable, ? extends Observable> f = onObservableAssembly;
if (f != null) {
return apply(f, source);
}
return source;
}
該函數是個hook函數 ,當設置hook函數的時候,會執行hook函數,默認情況下是沒有設置的,即是onObservableAssembly=null,此處我們可以忽略.所以
public static <T> Observable<T> create(ObservableOnSubscribe<T> source) 實際上返回的是new ObservableCreate<T>(source)
整個函數流程即是
new ObservableCreate<T>(source).subscribe(new Observer<Object>() {...}
ObservableCreate類:
//繼承Observable
public final class ObservableCreate<T> extends Observable<T> {
final ObservableOnSubscribe<T> source;
public ObservableCreate(ObservableOnSubscribe<T> source) {
//緩存 ObservableOnSubscribe 這個是我們聲明的
//new ObservableOnSubscribe<Object>() {
// @Override
// public void subscribe(ObservableEmitter<Object> emitter) throws Exception {
// emitter.onNext(1);
// emitter.onComplete();
// }
//}
this.source = source;
}
//實現Observable的抽象函數 這個是重點
@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);
}
}
...
}
我們現在知道了 ObservableCreate是Observable的一個實現類,接下來繼續走流程即是 .subscribe(new Observer<Object>(){})
,這個方法點進去是Observable的一個方法,
public abstract class Observable<T> implements ObservableSource<T> {
...
@SchedulerSupport(SchedulerSupport.NONE)
@Override
public final void subscribe(Observer<? super T> observer) {
//observer的非空判斷
ObjectHelper.requireNonNull(observer, "observer is null");
try {
//這個是和RxJavaPlugins.onAssembly()一樣的hook方法 默認不走
observer = RxJavaPlugins.onSubscribe(this, observer);
//判斷hook後的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;
}
}
....
//抽象方法
protected abstract void subscribeActual(Observer<? super T> observer);
....
}
我們前面在ObservableCreate類中,看到了其實現的subscribeActual方法
//實現Observable的抽象函數 這個是重點
@Override
protected void subscribeActual(Observer<? super T> observer) {
CreateEmitter<T> parent = new CreateEmitter<T>(observer);
//1
observer.onSubscribe(parent);
try {
//2
source.subscribe(parent);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
//3
parent.onError(ex);
}
}
上述1處:調用observer的onSubscribe方法
@Override
public void onSubscribe(Disposable d) {
Log.d("RxJava:", "onSubscribe");
}
上述2處:source.subscribe(parent);
在ObservableCreate類中我們看到 source是其保存的ObservableOnSubscribe實例,即是我們在代碼中實現的那個,調用.subscribe(parent)即是:
@Override
public void subscribe(ObservableEmitter<Object> emitter) throws Exception {
emitter.onNext(1);
emitter.onComplete();
}
上述3處 當初source.subscribe的過程中出現異常便會調用 CreateEmitter的onError的方法 最後調用Observer的onNext方法
我們現在知道了 Observable.create(ObservableOnSubscribe).subscribe(Observer)
實際上是: ObservableOnSubscribe.subscribe(new CreateEmitter(Observer)) ,ObservableOnSubscribe是我們前面實現的 類 ,
我們在其subscribe方法中進行,使用CreateEmitter發射數據 並最終調用complete()方法
接下來我們看下CreateEmitter
CreateEmitter類
static final class CreateEmitter<T>
extends AtomicReference<Disposable>
implements ObservableEmitter<T>, Disposable {
private static final long serialVersionUID = -3434801548987643227L;
final Observer<? super T> observer;
CreateEmitter(Observer<? super T> observer) {
//緩存我們設置的觀察者 Observer
this.observer = observer;
}
//該方法是我們在ObservableOnSubscribe的subscribe方法中調用的emitter.onNext(1);
@Override
public void onNext(T t) {
//先判斷髮射在數據是否爲null
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的方法,即是最後我們回調的方法
observer.onNext(t);
}
}
//在上述3中調用的onError方法 最終調用Observer的onError方法
@Override
public void onError(Throwable t) {
if (!tryOnError(t)) {
//設置hook方法 忽略
RxJavaPlugins.onError(t);
}
}
@Override
public boolean tryOnError(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方法
observer.onError(t);
} finally {
dispose();
}
return true;
}
return false;
}
//同上原理 先判斷是否取消訂閱
@Override
public void onComplete() {
if (!isDisposed()) {
try {
observer.onComplete();
} finally {
dispose();
}
}
}
//存儲Disposable類 用來判斷是否取消了訂閱
@Override
public void setDisposable(Disposable d) {
DisposableHelper.set(this, d);
}
@Override
public void setCancellable(Cancellable c) {
setDisposable(new CancellableDisposable(c));
}
@Override
public ObservableEmitter<T> serialize() {
return new SerializedEmitter<T>(this);
}
//取消訂閱
@Override
public void dispose() {
DisposableHelper.dispose(this);
}
//判斷是否取消了訂閱
@Override
public boolean isDisposed() {
return DisposableHelper.isDisposed(get());
}
@Override
public String toString() {
return String.format("%s{%s}", getClass().getSimpleName(), super.toString());
}
}
上述例子的整體流程如下:
- 生成ObservableOnSubscribe實例 實現其subscribe(ObservableEmitter emitter)方法,使用emitter發射數據
- 生成ObservableCreate實例,該類實現了Observable
- Observer訂閱Observable 調用ObservableCreate的subscribeActual(observer)
- 生成ObservableEmitter的實例CreateEmitter對象,調用Observer的onSubscribe的方法,
- 調用ObservableOnSubscribe的subscribe方法:即是我們上面實現的發射數據的方法
現在回答上面的兩個問題:
- RxJava中觀察者和被觀察者在ObservableCreate實例中是通過CreateEmitter類關聯起來的
- 被觀察者(Observable)發射數據是在訂閱後開始發射數據的 即是ObservableOnSubscribe調用subscribe方法
- Observable的整個流程圖如上面分析
爲了更直觀的分析其整個結構 下面畫出其UML類圖,
上面分析以及UML類圖中都指到了Disposable這個接口,該接口主要是實現判斷是否取消訂閱,如果取消訂閱則不再執行想要的回調,我們在CreateEmitter類中也看到了相關的代碼,
public interface Disposable {
/**
* Dispose the resource, the operation should be idempotent.
* 取消訂閱
*/
void dispose();
/**
* Returns true if this resource has been disposed.
* @return true if this resource has been disposed
* 是否取消訂閱
*/
boolean isDisposed();
}
在不同的Observable內的實現方式不同,這裏不在詳細說明