標籤(空格分隔): rxandroid rxjava map
上一篇文章分析了一層結構最簡單的事件觸發的過程,接下來分析map過程,對於map過程宏觀上的認識,借用官網上的一個圖
從這個圖中,我們可以看到,map的過程是一個一對一的過程,且針對的對象都是被觀察者Observable.由於rxjava是一種鏈式編程結構,因此一次map過程,就會增加一次層次機構。下面來看一個簡單的例子加以理解。
map(): 事件對象的直接變換
Observable<String> observable = Observable.create( new Observable.OnSubscribe<String>() {
@Override
public void call( Subscriber<? super String> subscriber ) {
Log.d( TAG, "OnSubscribe call: " );
subscriber.onNext( "123" );
subscriber.onCompleted();
}
} );
observable
.map( new Func1<String, Integer>() {
@Override
public Integer call( String s ) {
return 99;
}
} )
.subscribe( new Subscriber<Integer>() {
@Override
public void onCompleted() {
Log.d( TAG, "Subscriber onCompleted: " );
}
@Override
public void onError( Throwable e ) {
Log.d( TAG, "Subscriber onError: " );
}
@Override
public void onNext( Integer s ) {
Log.d( TAG, "Subscriber onNext: " + s );
}
} );
從這段code中來看,涉及的層次結構由前文的一層變成了兩層。
1.Observable.create創建了一個被觀察者Observable和它對應的OnSubscribe
2.Observable.map在上一個Observable的基礎上,再fork出一層,代碼之後,這裏會有一個新的Observable和相應的OnSubscribe對象
3.Observable.subscribe 發出命令,執行所有計劃表call方法,建立訂閱者鍊形結構,從最頂端的subscriber開始,按照指定的邏輯,一次回調所有subscriber的onNext方法。
圖文結構:
代碼分析:
1.Observable.create創建第一層Observable和ObSubsribe對象,如前文分析,這裏不再說明
2.Observable.map
public final <R> Observable<R> map(Func1<? super T, ? extends R> func) {
return lift(new OperatorMap<T, R>(func));
}
public final <R> Observable<R> lift(final Operator<? extends R, ? super T> operator) {
return new Observable<R>(new OnSubscribeLift<T, R>(onSubscribe, operator));
}
這裏調用map方法的是第一層結構中的Observable對象,此時它的模板類型爲T,從map中可以看到,map方法的返回值也是一個Observable,同時注意到模板類型由T變成了R,整個R是由入參func決定的,這也是爲什麼map操作之後,會影響此後所有的模板類型值。接下來調用lift方法,這個方法裏面就是新建了一個被觀察者Observable和其OnSubscribeLift< T, R >對象。因此完成了第二層Observable和其對應的ObSubscribe(這裏即是一個OnSubscribeLift)的對象的創建。
下面分析OperatorMap和OnSubscribeLift對象和Observable之間的關係。
a.OnSubscribeLift構造方法
public OnSubscribeLift(OnSubscribe<T> parent, Operator<? extends R, ? super T> operator) {
this.parent = parent;
this.operator = operator;
}
OnSubscribeLift的實現比較簡單,parent變量記錄了上一層Observable對象的計劃表OnSubscribe對象,operator變量記錄了具體的操作,對於map操作,這裏對應的是OperatorMap對象。
b.OperatorMap構造方法
public OperatorMap(Func1<? super T, ? extends R> transformer) {
this.transformer = transformer;
}
這個方法就是將map中Func1的操作保存至成員變量transformer中,接下來來分析這些結構的用處。
3.Observable.subscribe
首先,最初的Subscribe會被包裝成一個SafeSubsciber對象,然後這個訂閱者對象(SafeSubsciber)和map創建出來的被觀察者Observable對象之間,執行訂閱關係。如前文分析,此時這個被觀察者的計劃表ObSubscibe的call方法會被執行,這裏也就是執行OnSubscribeLift的call方法。
3.1 OnSubscribeLift.call
public void call(Subscriber<? super R> o) {
try {
Subscriber<? super T> st = hook.onLift(operator).call(o);
try {
// new Subscriber created and being subscribed with so 'onStart' it
st.onStart();
parent.call(st);
} catch (Throwable e) {
// localized capture of errors rather than it skipping all operators
// and ending up in the try/catch of the subscribe method which then
// prevents onErrorResumeNext and other similar approaches to error handling
Exceptions.throwIfFatal(e);
st.onError(e);
}
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
// if the lift function failed all we can do is pass the error to the final Subscriber
// as we don't have the operator available to us
o.onError(e);
}
}
這個call方法的實現邏輯也很簡單,即將它的下一級訂閱者委託給相應的operator對象的call方法去處理。前面分析到,operator這個操作符就是一個OperatorMap。
3.2 OperatorMap.call
@Override
public Subscriber<? super T> call(final Subscriber<? super R> o) {
MapSubscriber<T, R> parent = new MapSubscriber<T, R>(o, transformer);
o.add(parent);
return parent;
}
public MapSubscriber(Subscriber<? super R> actual, Func1<? super T, ? extends R> mapper) {
this.actual = actual;
this.mapper = mapper;
}
這裏的transformer保存的是map方法中的Func1對象,在這個call方法中,創建了一個MapSubscriber對象,這裏它也是一個Subscriber的子類,,成員變量actual保存了下層傳過來的subsciber,mapper中保存了Func1的操作。也即用了一個包裝者的模式,將前面的SafeSubsciber和transformer對象傳入,接下來返回到OnSubscribeLift.call方法中。接下來繼續分析OnSubscribeLift.call方法。
try {
// new Subscriber created and being subscribed with so 'onStart' it
st.onStart();
parent.call(st);
} catch (Throwable e) {
// localized capture of errors rather than it skipping all operators
// and ending up in the try/catch of the subscribe method which then
// prevents onErrorResumeNext and other similar approaches to error handling
Exceptions.throwIfFatal(e);
st.onError(e);
}
parent對象是上一層Observable對象的計劃表OnSubscribe對象,這幾行代碼,其實就模擬了一層訂閱的關係。這裏的訂閱者對象變成了MapSubscriber(包裝過一層結構SafeSubsciber對象),在我們這個例子中,如下call方法就會被執行,這裏入參subscriber即是MapSubscriber對象。
public void call( Subscriber<? super String> subscriber ) {
Log.d( TAG, "OnSubscribe call: " );
subscriber.onNext( "123" );
subscriber.onCompleted();
}
至此,在這個call方法中,真正的邏輯開始處理,MapSubscriber對象的onNext方法會被執行,如果沒有異常接下來onCompleted方法會被執行,否則onError方法會被執行。下面繼續分析
3.3 MapSubscriber.onNext
@Override
public void onNext(T t) {
R result;
try {
result = mapper.call(t);
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
unsubscribe();
onError(OnErrorThrowable.addValueAsLastCause(ex, t));
return;
}
actual.onNext(result);
}
在這裏mapper對象保存的是map方法中Func1的操作,這個方法的實現很簡單,就是做了一層攔截,將上一層執行下來的結果t (T),做了一次
mapper轉換,最終變成result(R),再將這個新的結果,給下層subsciber去繼續執行。
從圖文和代碼分析,可以知道,map操作其實就是新建了一層結構,在原始結果繼續向下執行的中間做了一次轉換,然後將轉換後的結果,繼續給下層結構去執行。