RXAndroid源碼分析(三) map過程

標籤(空格分隔): 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操作其實就是新建了一層結構,在原始結果繼續向下執行的中間做了一次轉換,然後將轉換後的結果,繼續給下層結構去執行。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章