最近一直沒有機會,好好寫博客,可能還是太浮躁了,自己對自己的這種狀態也不是特別滿意。近幾日準備安下心來,好好研究一下RxJava,把這期間的所得總結成一個系列,盡量都寫博客中,看看這個階段結束時自己能達到怎么樣的程度。
概述
在日常的Android項目開發中,RxJava+Retrofit是一個萬金油網絡請求框架,通常情況下,我們的代碼大概是這樣的:
public void requestUserInfo(String userName) {
serviceManager.getUserInfoService()
.getUserInfo(userName)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(info -> {
//do something
});
}
事實上,我很少去關心RxJava內部是如何實現的,因為這樣我也能夠輕松定制項目中的網絡請求需求,并且寫出看起來還不錯的代碼。
但是很快我就事與愿違了,因為在測試RxJava相關的業務代碼時,面對需要測試的代碼塊,我束手無策,我接連踩到了很多坑。雖然最后我都通過萬能的google一一解決了,但是我已經不滿足現狀,我可以輕易提出很多個讓我疑惑的問題:
1 RxJavaPlugin是干什么的
2 鏈式調用中當存在數個Observable.subscribeOn()時的處理方式
3 鏈式調用中當存在數個Observable.observeOn()時的處理方式
4 數據是如何經過操作符進行的處理
5 各個doOnXXX()方法回調所在的線程?
等等......
于是我就有了這個念頭:研究源碼,徹底將它整明白。
源碼版本
RxJava官方Github: https://github.com/ReactiveX/RxJava
Branch:2.x (RxJava2)
版本號:2.1.3
一.基本流程
我決定從簡單的代碼入手分析RxJava2:
public class RxJavaTest {
@Test
public void test() throws Exception {
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
e.onNext(1);
e.onNext(2);
e.onComplete();
}
}).subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable d) {}
@Override
public void onNext(Integer integer) {
System.out.println(String.valueOf(integer));
}
@Override
public void onError(Throwable e) {}
@Override
public void onComplete() {}
});
}
}
代碼很簡單,我們可以簡單分成兩步:
1.Observable.create()
2.Observable.subscribe()
一步步進行分析。
二.Observable.create()
我們點擊進入Observable.create()方法的內部:
public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
//...(表示排除非關鍵代碼,下同)
return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
}
可以看到,create方法的返回值仍然是一個Observable,這是當然的,我們看到RxJavaPlugins.onAssembly():
/**
* Calls the associated hook function.
*/
public static <T> Observable<T> onAssembly(@NonNull Observable<T> source) {
//...
}
這是一個hook方法,我們暫時先忽略它,默認這個方法就是返回了直接返回source,即傳入的參數對象,那么實際上,create方法的關鍵就是下面這行代碼:
return new ObservableCreate<T>(source);
來看看這個ObservableCreate是何方神圣:
//1.ObservableCreate是Observable的子類
public final class ObservableCreate<T> extends Observable<T> {
final ObservableOnSubscribe<T> source;
//2.注意這里,實際上Observable.create方法執行了下面的代碼
public ObservableCreate(ObservableOnSubscribe<T> source) {
this.source = source;
}
//3.subscribeActual方法是Observable.subscribe()后才執行的
@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);
}
}
}
我已經把重點標記了,可以得知:
- 1.ObservableCreate本身就是Observable的子類,因此Observable.create()實際上就是創建并返回一個ObservableCreate對象;
- 2.在ObservableCreate的構造函數中,實際上是將create()方法中的參數ObservableOnSubscribe依賴注入ObservableCreate中并保存;
- 3.subscribeActual()方法是在Observable.subscribe()訂閱時執行的,我們先知道這點,一會再詳細介紹它。
現在關于ObservableCreate這個類本身我們基本都了解了,我們來看看我們傳進來的ObservableOnSubscribe是什么:
public interface ObservableOnSubscribe<T> {
/**
* Called for each Observer that subscribes.
*/
void subscribe(@NonNull ObservableEmitter<T> e) throws Exception;
}
原來ObservableOnSubscribe只是一個接口,它就是我們傳進來的這個:
Observable.create(new ObservableOnSubscribe<String>() {
//就是它
@Override
public void subscribe(ObservableEmitter<String> e) throws Exception {
e.onNext(1);
e.onNext(2);
e.onComplete();
}
}).subscribe(...);
實際上,ObservableOnSubscribe就是讓我們去實現的接口,我們將要發射的事件都通過ObservableEmitter發射器對象進行發射(本文中是依次發射Integer 1、2),可以說,在本文的案例中,ObservableOnSubscribe就是數據流的源頭。
整理思路
現在我們已知的情報,在Observable調用create()方法時:
- 1.我們實現了ObservableOnSubscribe接口,并在接口的subscribe方法中,傳入了數據源,這些數據源需要通過ObservableEmitter進行發射。
- 2.在create()方法中,拋開hook不談,實際上方法內部是創建了一個ObservableCreate對象并返回,這個ObservableCreate類本身就是Observable的子類
- 3.在ObservableCreate的構造方法中,將我們實現的ObservableOnSubscribe(定義事件的發射順序)作為成員保存在ObservableCreate中。
現在基本已經清楚了,但是我們還有兩個問題需要解答:
1.ObservableEmitter發射器對象何時實例化并發射數據?
2.接下來如何才能實現Observable的訂閱?
三.Observable.subscribe()
我們點擊進入查看Observable.subscribe()源碼:
public final void subscribe(Observer<? super T> observer) {
//...
try {
//...
//1.我們只需要關注下面這行代碼
subscribeActual(observer);
} catch (NullPointerException e) {
throw e;
} catch (Throwable e) {
//...
}
}
拋開非核心代碼和hook相關代碼,我們可以看到,當我們調用 Observable.subscribe(observer)方法時,實際上就是調用Observable.subscribeActual(observer)方法。
應該清楚的記得,在本文中,此時執行subscribe()方法的Observable,實際上應該就是ObservableCreate對象。
因此,Observable.subscribe(observer),實際上執行的是下面的代碼:
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) {
//1.請注意,參數中的observer實際上就是我們要打印onNext的observer
//2.實例化CreateEmitter對象
CreateEmitter<T> parent = new CreateEmitter<T>(observer);
//3.執行observer的onSubscribe方法,這里可以看到:
// onSubscribe()回調所在的線程是ObservableCreate執行subscribe()所在的線程
// 和subscribeOn()/observeOn()無關!
observer.onSubscribe(parent);
try {
//4.ObservableOnSubscribe執行subscribe()方法
//這個方法就是我們在create()中定義的代碼
//其實就是發射數據源,parent是CreateEmitter
source.subscribe(parent);
} catch (Throwable ex) {
//5.異常處理
Exceptions.throwIfFatal(ex);
parent.onError(ex);
}
}
}
整理思路
我把需要解釋的基本都放到了注釋中,簡單總結一下流程:
- 1.在Observable執行subscribe方法時,實際上是執行了ObservableCreate.subscribeActual()方法,并將我們打印數據的回調Observer作為參數傳了進去
- 2.在subscribeActual方法內部,首先示例化了一個CreateEmitter發射器對象,然后執行Observer的onSubscribe()回調。
- 3.之后,就是執行一開始我們在代碼中聲明的ObservableOnSubscribe對象的subscribe方法,開始通過CreateEmitter發射器發射數據,即執行:
public void subscribe(ObservableEmitter<String> e) throws Exception {
e.onNext(1);
e.onNext(2);
e.onComplete();
}
現在的問題是,僅僅通過發射器ObservableEmitter.onNext(1),我們需要的打印代碼哪里去了?
Observable.create(//...)
.subscribe(new Observer<Integer>() {
//...
@Override
public void onNext(Integer integer) {
System.out.println(String.valueOf(integer));
}
//...
});
我們拐回到這行代碼:
protected void subscribeActual(Observer<? super T> observer) {
//...
//2.實例化CreateEmitter對象
CreateEmitter<T> parent = new CreateEmitter<T>(observer);
//...
}
我們來看看CreateEmitter這個類:
static final class CreateEmitter<T>
extends AtomicReference<Disposable>
// 1.請注意,CreateEmitter實現了Disposable接口
// 這也就說明了在執行上面subscribeActual()步驟3 observer.onSubscribe()的回調時,可以將ObservableEmitter作為參數傳入了
// ObservableEmitter也是Disposable
implements ObservableEmitter<T>, Disposable {
private static final long serialVersionUID = -3434801548987643227L;
final Observer<? super T> observer;
//2.初始化時,會將打印數據的回調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()) {
//3.在ObservableEmitter.onNext()發射數據時,實際上調用了observer的onNext()回調打印數據
observer.onNext(t);
}
}
// 4(額外):當執行onError()時,會執行dispose()方法取消訂閱
@Override
public void onError(Throwable t) {
if (!tryOnError(t)) {
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(t);
} finally {
dispose();
}
return true;
}
return false;
}
// 5(額外):當執行onError()時,會執行dispose()方法取消訂閱
//這也就說明為什么 onComplete()和onError()方法只能觸發其中的一個了
@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<T> serialize() {
return new SerializedEmitter<T>(this);
}
@Override
public void dispose() {
DisposableHelper.dispose(this);
}
@Override
public boolean isDisposed() {
return DisposableHelper.isDisposed(get());
}
}
基本都寫到了注釋中,應該不難理解。
總結
分析一下各個類的職責:
- Observable :個人理解是裝飾器模式下的基類,實際上所有操作都是Observable的子類進行的實現
- ObservableOnSubscribe: 接口,定義了數據源的發射行為
- ObservableCreate: 裝飾器模式的具體體現,內部存儲了數據源的發射事件,和subscribe訂閱事件
- ObservableEmitter: 數據源發射器,內部存儲了observer
- Observer: 接收到數據源后的回調(比如打印數據等)
簡單總結一下:
1.Observable.create(),實例化ObservableCreate和ObservableOnSubscribe,并存儲數據源發射行為,準備發射(我已經準備好數據源,等待被訂閱)
2.Observable.subscribe(),實例化ObservableEmitter(發射器ObservableEmitter準備好!數據發射后,數據處理方式Observer已準備好?。?br>
3.執行Observer.onSubscribe()回調,ObservableEmitter作為Disposable參數傳入
4.執行ObservableOnSubscribe.subscribe()方法 (ObservableEmitter發射數據,ObservableEmitter內部的Observer處理數據)
此外我們還可以得到的:
5.CreateEmitter 中,只有Observable和Observer的關系沒有被dispose,才會回調Observer的onXXXX()方法。
6.Observer的onComplete()和onError() 互斥只能執行一次,因為CreateEmitter在回調他們兩中任意一個后,都會自動dispose()。
7.onSubscribe()是在我們執行subscribe()這句代碼的那個線程回調的,并不受線程調度影響。
參考
1.RxJava2 源碼解析(一)@張旭童
http://www.lxweimin.com/p/23c38a4ed360
2.RxJava2 源碼解析——流程 @Robin_Lrange
http://www.lxweimin.com/p/e5be2fa8701c