本片文章適用于有一定Android開發經驗并且對于響應式編程有一定了解的程序猿閱讀。
簡介
RxJava按照官方的定義為:一個在 Java VM 上使用可觀測的序列來組成異步的、基于事件的程序的庫。在Android上使用的比較廣泛,因為在移動開發中由于UI線程不能阻塞,否則會出現卡頓,所以異步操作對于移動端編程尤其重要。而RxJava就是這樣一個基于事件流并且便于異步操作的程序庫。下面我們從源碼角度分析一下事件的創建流程。
Demo
Observable observable = Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> emitter) throws Exception {
emitter.onNext("hello");
emitter.onNext("world");
emitter.onComplete();
}
});
Observer observer = new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "onSubscribe");
}
@Override
public void onNext(String value) {
Log.d(TAG, "onNext data is :" + value);
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "onError data is :" + e.toString());
}
@Override
public void onComplete() {
Log.d(TAG, "onComplete");
}
};
observable.subscribe(observer);
輸出:
onSubscribe
onNext data is :hello
onNext data is :world
onComplete
從日志可以看出onSubscribe方法先被調用然后依次輸出hello world 最后輸出 onComplete 符合Observable 中subscribe方法的調用順序。
Observable#create
@SchedulerSupport(SchedulerSupport.NONE)
public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
ObjectHelper.requireNonNull(source, "source is null");
return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
}
Observable.create()的入參為ObservableOnSubscribe,那ObservableOnSubscribe是什么呢,它是一個接口
public interface ObservableOnSubscribe<T> {
/**
* Called for each Observer that subscribes.
* @param e the safe emitter instance, never null
* @throws Exception on error
*/
void subscribe(ObservableEmitter<T> e) throws Exception;
}
ObjectHelper.requireNonNull()對入參進行了空指針判斷。
RxJavaPlugins根據注釋來看其實就是一個對Rxjava標準操作進行處理的插件類。
RxJavaPlugins.onAssembly返回的其實就是new 出來的ObservableCreate對象,同時持有ObservableOnSubscribe對象引用。
那ObservableCreate又是什么呢?其實ObservableCreate就是一個Observable被觀察者對象并重寫了subscribeActual()方法。而subscribeActual()真正調用的地方發生在訂閱發生的地方,下文會分析到。
所以Observable#create最終創建的是ObservableCreate對象。
Observable#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;
} 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;
}
}
可以看到RxJavaPlugins.onSubscribe(this,observer)其實只是簡單的返回了observer而已,關鍵的是subscribeActual(observer)。通過上文可知,subscribeActual真正發生的地方其實是在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);
}
}
subscribeActual這段代碼并不長但很重要,咱們一句一句來分析下。
CreateEmitter<T> parent = new CreateEmitter<T>(observer);
采用的是組合的方式,parent 內部持有了observer對象僅此而已,可以理解為parent 為observer的代理。
然后observer調用了自己的onSubscribe方法,這也是為什么我們一開始看到onSubscribe日志最先輸出的原因。同時它也脫離了被訂閱者的管理,因為訂閱者自己調用了自己。
接下來可以看到訂閱真正發生的地方source.subscribe(parent);
source就是一開始我們new出來的ObservableOnSubscribe對象,而parent是訂閱者的代理對象,所以當訂閱發生的時候,就會輸出上面的日子。
單個操作符訂閱總結
1、傳入的ObservableOnSubscribe最終被用來創建成ObservableCreate
2、ObservableCreate持有我們的被觀察者對象以及重新了訂閱觸發時的回調函數subscribeActual
3、在subscribeActual實現了我們的主要邏輯,包括observer.onSubscribe(parent);
source.subscribe(parent);
parent.onError(ex)的調用
4、在Observable的subscribe被調用時開始執行事件分發流程
5、最后放一張對象間的關系圖(此圖來自于網絡)
組合操作符總結
1、首先我們得明確一點每個操作符最后都會通過RxJavaPlugins.onAssembly(Observable<T> source)返回一個新的Observable。如下:
2、onAssembly的入參針對每一個操作符都會實現一個繼承自AbstractObservableWithUpstream:Observable的對象,它的作用就是用于包裝上級的AbstractObservableWithUpstream:Observable。比如:
而每一個新的Observable對象中都會有一個繼承自Observer的對象,它的作用就是用于包裝下級Observer和當前的Function
3、當我們調用最底層subscribe方法的時候其實真正調用的是上一級Observable的subscribeActual方法,然后subscribeActual方法中會構造一個內部Observer子類的對象,然后通過調用上級Observable的subscribe方法將新生成的包裝Observer對象傳入到上一級中。
4、通過一層層的包裝上傳,當調用鏈來到最頂層的ObservableCreate時,由于不能再往上一層進行封裝了,就會執行ObservableOnSubscribe的subscribe方法,如下:
而subscribe方法的參數就是下級經過層層包裝傳遞上來的Observer,所以當我們調用emitter的相關方法時,內部都會執行如下操作:
其中actual就是下級的Observer。
5、當往下的調用鏈來到最底層時自然調用的就是最底層Observer的相關方法了。
至此,組合操作符的調用鏈就分析完了。