前言:上一篇文章RxJava2原始碼分析(一):基本流程分析,是對RxJava2基本流程的分析,有了上一篇的基礎,這篇就再深入一點,開始分析一下RxJava2操作符的原理。
為了方便理解RxJava2操作符的原理,這裡選擇最常用的map
操作符來講解操作符的原理,示例程式碼如下
private void basicUseRxJava() {
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
}
}).map(new Function<Integer, String>() {
@Override
public String apply(Integer integer) throws Exception {
return "我是數字" + integer;
}
}).subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(String s) {
Log.e("wizardev", "onNext: " + s);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
}
複製程式碼
內容回顧
因為這一篇的內容是在上一篇的基礎上進行講解的,所以在講解操作符之前,先回顧一下前一篇主要的知識,如下:
- Observable執行的create方法後返回的是ObservableCreate例項。
- create方法的引數,實際是注入到ObservableCreate類中,作為它的成員變數。
- 呼叫Observable的subscribe方法最終呼叫的是ObservableCreate類中的subscribeActual方法。
操作符分析
同樣,這裡分析原始碼的順序依然按照程式碼的執行順序,create
方法前文已經分析過了,這裡就直接看map
方法,map
方法的程式碼如下
public final <R> Observable<R> map(Function<? super T, ? extends R> mapper) {
ObjectHelper.requireNonNull(mapper, "mapper is null");
return RxJavaPlugins.onAssembly(new ObservableMap<T, R>(this, mapper));
}
複製程式碼
有了前一篇的經驗,可以直接從這個方法中得出結論即map
方法返回的是ObservableMap例項,同時將map
方法的引數及Observable自身注入了其構造方法中。
現在看下ObservableMap類的原始碼,如下
public final class ObservableMap<T, U> extends AbstractObservableWithUpstream<T, U> {
final Function<? super T, ? extends U> function;
public ObservableMap(ObservableSource<T> source, Function<? super T, ? extends U> function) {
super(source);//呼叫了其父類的構造方法
this.function = function;
}
@Override
public void subscribeActual(Observer<? super U> t) {
source.subscribe(new MapObserver<T, U>(t, function));
}
//省略部分無關程式碼
//...
}
複製程式碼
從上面的程式碼中可以看出,ObservableMap
繼承至AbstractObservableWithUpstream
,繼續進入AbstractObservableWithUpstream
類中看下原始碼,如下
abstract class AbstractObservableWithUpstream<T, U> extends Observable<U> implements HasUpstreamObservableSource<T> {
protected final ObservableSource<T> source;
AbstractObservableWithUpstream(ObservableSource<T> source) {
this.source = source;
}
@Override
public final ObservableSource<T> source() {
return source;
}
}
複製程式碼
從上面的一段程式碼,可以知道AbstractObservableWithUpstream
類其實就是Observable
類的裝飾類,這個類的作用就是將例項化的Observable
注入進來,作為其成員變數。分析到這裡可以得出這幾個類的關係如下
注:ObservableMap中的成員變數function
就是我們寫的這段程式碼
new Function<Integer, String>() {
@Override
public String apply(Integer integer) throws Exception {
return "我是數字" + integer;
}
}
複製程式碼
好了,到這裡算是將map
方法所做的事情分析完了,下面來看例項程式碼的最後一個方法subscribe
.
subscribe方法分析
通過上一篇文章可以知道subscribe
方法實際呼叫的是Observable子類的subscribeActual
方法,而這裡呼叫subscribe
方法的類是ObservableMap
,所以這裡呼叫的就是ObservableMap
類的subscribeActual
方法。現在來看下ObservableMap類的subscribeActual
方法的原始碼,如下(為了分析方便,這裡將與subscribeActual方法有關的程式碼一起貼了出來)
final Function<? super T, ? extends U> function;
public ObservableMap(ObservableSource<T> source, Function<? super T, ? extends U> function) {
super(source);
this.function = function;
}
@Override
public void subscribeActual(Observer<? super U> t) {
source.subscribe(new MapObserver<T, U>(t, function));
}
複製程式碼
從上面的程式碼可以發現ObservableMap
類的subscribeActual
方法又呼叫了其上游的subscribe
方法,為了便於理解這裡解釋一下文中所說的上游下游
文中說的“上游”及“下游”其實是相對而言的,這裡的“上游”是靠近Observable的,如示例程式碼中的subscribe是最下游,map是其上游,而map操作符又是crate方法的下游。
這裡上游的subscribe
方法就是ObservableCreate呼叫的subscribe
方法,實際就是呼叫ObservableCreate的subscribeActual
方法,接著就是前一篇講過的流程了。
結論
分析到現在可以得出以下結論
subscribe
方法的呼叫流程是從下往上的,就是從下游往上游分別呼叫其subscribe
方法。
為了方便理解,這裡我用時序圖表示subscribe
的呼叫順序,如下圖
接收資料流程分析
上面的內容分析了RxJava2基本流程加入操作符後的subscribe
方法的執行順序,接著就來看下,資料的接收順序。經過上面的分析可以知道最終呼叫的是ObservableCreate類的subscribeActual
方法,這裡與前一篇文章subscribeActual
方法不同的就是subscribeActual
方法的引數改變了,這裡的引數是MapObserver
類的例項,再來看下ObservableCreate類的subscribeActual
方法的原始碼,如下
//這裡的引數實際是MapObserver類的例項
protected void subscribeActual(Observer<? super T> observer) {
CreateEmitter<T> parent = new CreateEmitter<T>(observer);
observer.onSubscribe(parent);
try {
//這句程式碼的最終呼叫的就是MapObserver類的onNext方法。
source.subscribe(parent);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
parent.onError(ex);
}
}
複製程式碼
一些重要的內容已經在上面的程式碼中進行了註釋,可能這句source.subscribe(parent);
程式碼,不好理解,這裡就來解釋一下這句程式碼,由上一篇文章可知,這裡的source
就是示例程式碼中的new ObservableOnSubscribe<Integer>()...
例項,這裡就是呼叫了這個例項的subscribe
方法,而這個方法中的程式碼就是呼叫了其引數的onNext
方法,**最終呼叫的就是MapObserver類的onNext方法。**現在,來看下MapObserver類的onNext方法的程式碼,如下
@Override
public void onNext(T t) {
if (done) {
return;
}
if (sourceMode != NONE) {
downstream.onNext(null);
return;
}
U v;
try {
//1、
v = ObjectHelper.requireNonNull(mapper.apply(t), "The mapper function returned a null value.");
} catch (Throwable ex) {
fail(ex);
return;
}
//2、
downstream.onNext(v);
}
複製程式碼
主要來看下v = ObjectHelper.requireNonNull(mapper.apply(t), "The mapper function returned a null value.");
這句程式碼,這句程式碼中的mapper就是注入到ObservableMap中的成員變數function,詳細內容可以檢視原始碼。呼叫的apply方法,就是示例程式碼中的這句程式碼
@Override
public String apply(Integer integer) throws Exception {
return "我是數字" + integer;
}
複製程式碼
接著,可以發現又呼叫了“2”處的程式碼downstream.onNext(v);
,這句程式碼中的downstream
就是示例程式碼中最下游的subscribe
方法中的引數即是下面的程式碼
new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(String s) {
Log.e("wizardev", "onNext: " + s);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
}
複製程式碼
所以這句downstream.onNext(v);
呼叫的就是new Observer<String>()
匿名類中的onNext
方法。關於downstream
的是何時初始化的,可以從MapObserver的父類BasicFuseableObserver類中知曉。
結論
分析到這裡,又可以得出一些結論
- 關於資料的處理上從上游到下游一級級的處理的。
- 在MapObserver類中的
onNext
方法,首先呼叫的是function
中的apply
方法,然後再呼叫下游的onNext
方法並將處理後的引數傳入。
總結
通過分析map
操作符,可以知道訂閱方法(subscribe)是從下游到上游進行訂閱的,而資料的發射是從上游到下游進行的。這兩個特性不僅僅是map
操作符的特性,對其他的操作符同樣適用。為了講清楚這兩個特性,本文就選了比較具有代表性的map
操作符,如果想了解其他操作符的原理,就順著這兩個特性分析就行了。
授之以魚,不如授之以漁。本文的目的就是解釋清楚操作符的思想及原理,理解了這種思想及原理,分析其他的操作符也就不在話下了。