一、前言
RxJava是什么呢?根據
RxJava
在GitHub
上給出的描述
RxJava – Reactive Extensions for the JVM – a library for composing asynchronous and event-based programs using observable sequences for the Java
大致意思是:一個可以在JVM上使用的,是由異步的基于事件編寫的通過使用可觀察序列構成的一個庫。
關鍵詞:異步
,基于事件
,可觀察序列
之前只是了解了Rx1.x時候的源碼和使用方式,由于當時成員技術棧不統一,就沒有在產品中使用。現在隨著Rx的持續發熱,身為主程的我依然留著對rx的喜愛,故現決定引入rx。
雖然有過使用rx的經歷,但是現在rx升級到了2.0的版本,變化幅度還是蠻大的,所以抱著從0開始的心態,從新學習Rx2.X的相關代碼及使用注意事項。
本次學習歷程所定目標如下:
1.初步了解RxJava2.X的使用流程
2.探索Observable
發送數據的流程
3.明白Observer
是如何接收數據的
4.解析Observable
與Observer
的勾搭(如何關聯)過程
5.探索RxJava線程切換的奧秘
6.了解RxJava操作符的實現原理本次學習基于RxJava2.1.1版本的源碼
二、從Demo到原理
//1、觀察者創建一個Observer
Observer observer = new Observer() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.d(TAG, "onSubscribe");
}
@Override
public void onNext(@NonNull String s) {
Log.d(TAG, "onNext data is :" + s);
}
@Override
public void onError(@NonNull Throwable e) {
Log.d(TAG, "onError data is :" + e.toString());
}
@Override
public void onComplete() {
Log.d(TAG, "onComplete");
}
};
Observable observable = Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(@NonNull ObservableEmitter e) throws Exception {
e.onNext("hello");
e.onNext("world");
e.onComplete();
}
});
observable.subscribe(observer);
-
結果輸出:
onSubscribe onNext data is :hello onNext data is :world onComplete
可以看到,Observer的onSubscribe是最先被調用的,這個用什么用呢?我們后面會講到。
-
OK,從哪開始入手呢?
Observable.create
,嗯,整個流程是從create開始的,那么我們就從源頭開始吧。先看一下create,他會煩的是一個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(@NonNull ObservableEmitter<T> e) throws Exception; }
-
該接口會接收一個ObservableEmitter的一個對象,然后通過該對象我們可以發送消息也可以安全地取消消息,我們繼續看ObservableEmitter這個借口類
public interface ObservableEmitter<T> extends Emitter<T> { void setDisposable(@Nullable Disposable d); void setCancellable(@Nullable Cancellable c); boolean isDisposed(); @NonNull ObservableEmitter<T> serialize(); @Experimental boolean tryOnError(@NonNull Throwable t); }
-
ObservableEmitter是對Emitter的擴展,而擴展的方法證實RxJava2.0之后引入的,提供了可中途取消等新能力,我們繼續看Emitter
public interface Emitter<T> { void onNext(@NonNull T value); void onError(@NonNull Throwable error); void onComplete(); }
-
里面的三個方法使用過rx的應該非常眼熟了??吹竭@里,我們只是了解了傳遞參數的數據結構,了解到的信息還是比較少的。我們繼續看下create內部做了什么操作呢?
public static <T> Observable<T> create(ObservableOnSubscribe<T> source) { ObjectHelper.requireNonNull(source, "source is null"); return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source)); }
RxJavaPlugins或許你會很陌生,其實我也很陌生,不過沒關系,我覺得后面會經常遇到RxJavaPlugins,熟悉它是必然的;
可以看到我們傳入ObservableOnSubscribe被用來創建ObservableCreate,其實ObservableCreate就是Observable的一個實現類哦。
思路梳理
- OK,到這里我們先梳理一下思路:
1、Observable通過調用create創建一個Observable
2、調用create時需要傳入一個ObservableOnSubscribe類型的實例參數
3、最終傳入的ObservableOnSubscribe類型的實例參數作為ObservableCreate構造函數的參數傳入,一個Observable就此誕生了
-ObservableCreate又是個什么東東呢?我們分步來,先看ObservableCreate的兩個方法
public final class ObservableCreate<T> extends Observable<T> {
final ObservableOnSubscribe<T> source;
public ObservableCreate(ObservableOnSubscribe<T> source) {
this.source = source;
}
@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);
}
}
.....
}
source:Observable.createc傳入的ObservableOnSubscribe實例
-
subscribeActual回調方法,它在調用Observable.subscribe時被調用,即與觀察者或則訂閱者發生聯系時觸發。subscribeActual也是實現我們主要邏輯的地方,我們來仔細分析下subscribeActual方法:
1、首先subscribeActual傳入的參數為Observer類型,也就是我們subscribe時傳入的觀察者,到底是不是呢?后面會分析到。
2、傳入的Observer會被包裝成一個CreateEmitter,CreateEmitter
繼承了AtomicReference提供了原子級的控制能力。RxJava2.0提供的新特性與之息息相關哦,這個我們先給它來個關鍵標簽,后面再詳細分析。
3、 觀察者(observer)調用自己的onSubscribe(parent);將包裝后的observer傳入。這個也是RxJava2.0的變化,真正的訂閱在source.subscribe(parent);
這句代碼被執行后開始,而在此之前先調用了onSubscribe方法來提供RxJava2.0后引入的新能力(如中斷能力)。從這里我們也就知道了為何觀察者的onSubscribe最先被調用了。(被訂閱者說:我也很無辜,他自己調用了自己,我也控制不了╮(╯_╰)╭)
4、被訂閱者或者說被觀察者(source)調用subscribe訂閱方法與觀察者發生聯系。這里進行了異常捕獲,如果subscribe拋出了未被捕獲的異常,則調用 parent.onError(ex);
5、在執行subscribe時也就對應了我們demo中的public void subscribe(@NonNull ObservableEmitter e) throws Exception { e.onNext("hello"); e.onNext("world"); e.onComplete(); }
-
Ok,看來subscribeActual這個回調確實很重要,前面我們也說了subscribeActual回調方法在Observable.subscribe被調用時執行的,真的像我說的一樣么?萬一我看走眼了
@SchedulerSupport(SchedulerSupport.NONE) @Override public final void subscribe(Observersuper 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; } }
OK,代碼不多,可以看到RxJavaPlugins.onSubscribe(this, observer);,我們RxJava2.0中的Hook能力就是來自這里了。然后繼續看下面subscribeActual(observer);被調用了。
思路梳理
1、傳入的ObservableOnSubscribe最終被用來創建成ObservableOnSubscribe
2、ObservableOnSubscribe持有我們的被觀察者對象以及訂閱時所觸發的回調subscribeActual
3、在subscribeActual實現了我們的主要邏輯,包括observer.onSubscribe(parent);
,source.subscribe(parent);
,parent.onError(ex);
的調用
4、在Observable的subscribe被調用時開始執行事件分發流程。
三、總結
- 本次,我們只是實現了我們6個目標中的一小部分,通過本次,我們對于RxJava的神秘感是否又消失了一點呢?
- 后面的Rx系列文章將會循序漸進,逐步分析RxJava的各個神秘點。