RxJava源碼淺析———訂閱流程、map與Filter操作符實現原理

RxJava源碼淺析———訂閱流程、map與filter操作符實現原理

RxJava是一個非常流行的基於觀察者模式的響應式編程框架,在Android開發等領域有很廣泛的應用。作爲Java開發者,我們有必要了解一下RxJava的實現原理,掌握RxJava的設計思想,這樣我們才能更加熟練的使用RxJava來編寫優秀的代碼。

訂閱流程

要使用RxJava,首先要創建一個被觀察者Observable對象。我們通常是使用Observable的create方法來創建一個Observable對象的,如下:

    Observable<Integer> observable = Observable.create(new ObservableOnSubscribe<Integer>() {
        @Override
        public void subscribe(ObservableEmitter<Integer> e) throws Exception {
            e.onNext(new Integer(1));
            e.onNext(new Integer(2));
            e.onComplete();
        }
    });    

我們來看一下create方法的源碼:

    public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
        ObjectHelper.requireNonNull(source, "source is null");
        return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
    }

在create方法中,首先對被傳入的參數ObservableOnSubscribe對象進行了空檢查,然後new了一個ObservableCreate對象,並將這個對象作爲參數傳入了RxJavaPlugins.onAssembly方法中,我們首先來看onAssembly方法的源碼:

    public static <T> Observable<T> onAssembly(@NonNull Observable<T> source) {
        Function<? super Observable, ? extends Observable> f = onObservableAssembly;
        if (f != null) {
            return apply(f, source);
        }
        return source;
    }

在onAssembly方法中首先判斷onObservableAssembly對象是否爲null,如果不爲null則調用apply方法並返回結果,如果爲null則直接返回傳入的參數。在默認情況下onObservableAssembly爲null,也就是說默認情況下onAssembly方法其實什麼都沒有做,直接將傳入的Observable對象返回了。

回到Observable的create方法,我們再來看new ObservableCreate到底做了什麼,ObservableCreate類的構造方法如下:

    public final class ObservableCreate<T> extends Observable<T> {
        final ObservableOnSubscribe<T> source;

        public ObservableCreate(ObservableOnSubscribe<T> source) {
            this.source = source;
        }

        ...
    }    

ObservableCreate類的構造方法很簡單,直接將傳入的ObservableOnSubscribe對象保存在了自己的一個全局變量source中,並且這個變量被final所修飾。而我們通過分析ObservableCreate類可以發現,ObservableCreate繼承自Observable,也就是說ObservableCreate本身也是一個被觀察者對象。

通過上面的分析我們可以看出,Observable.create方法其實就是創建了一個ObservableCreate對象,並把一個ObservableOnSubscribe保存在了這個ObservableCreate中。

創建完Observable,我們便可以調用它的subscribe方法來關聯相應的觀察者:

    observable.subscribe(new Observer<Integer>() {
        @Override
        public void onSubscribe(Disposable d) {
            Log.e("RxJava", "onSubscribe");
        }

        @Override
        public void onNext(Integer integer) {
            Log.e("RxJava", "onSubscribe" + integer.toString());
        }

        @Override
        public void onError(Throwable e) {
            Log.e("RxJava", "onError");
        }

        @Override
        public void onComplete() {
            Log.e("RxJava", "onComplete");
        }
    });

我們來看一下subscribe方法的源碼:

    public final void subscribe(Observer<? super T> observer) {
        ObjectHelper.requireNonNull(observer, "observer is null");
        try {
            observer = RxJavaPlugins.onSubscribe(this, 
                observer);//同上面的RxJavaPlugins.onAssembly方法,默認情況下直接將observer返回

            ObjectHelper.requireNonNull(observer, "Plugin returned null Observer");

            subscribeActual(observer);
        } catch (NullPointerException e) { // NOPMD
         ...
        }
    }

subscribe方法中先檢查了observer對象是否爲null,然後調用了RxJavaPlugins.onSubscribe方法,該方法默認情況下什麼都不做直接將observer對象返回,然後又調用了subscribeActual方法。上面我們分析過,create方法生成的Observable其實是一個ObservableCreate對象,因此我們看一下ObservableCreate類中的subscribeActual方法:

    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);
        }
    }

可以看到在subscribeActual方法中先生成了一個Emitter事件發射器,然後直接調用了observer的onSubscribe方法,因此onSubscribe方法纔可以在事件發射之前被執行。然後又調用了source.subscribe方法,前面我們說過,這個source對象就是在create方法調用時傳入的ObservableOnSubscribe對象,此時ObservableOnSubscribe的subscribe方法就被調用了,各種事件也被成功的發射出去了。並且通過源碼可以看出,如果在調用subscribe方法時出現異常,則會直接讓Emitter發射一個onError事件。

至此一個最簡單的訂閱流程就完成了。

事件的發射

上面我們簡單的分析了Rxjava的訂閱流程,可見事件最終是在subscribeActual方法中調用source.subscribe(parent)來發射的。我們在subscribeActual方法中生成了一個CreateEmitter對象,並將這個Emmitter傳入了onSubscribe方法中。通過本文最開始的那個例子可以看出,各種事件其實是由這個Emmitter來發射的,我們首先看一下CreateEmmitter對象的構造方法:

    CreateEmitter(Observer<? super T> observer) {
        this.observer = observer;
    }

可見在CreateEmmitter中持有了Observer對象。我們可以通過CreateEmmitter的onNext、onComplete和onError方法來發射各種事件,在這裏以onNext的源碼爲例看一下Emmitter究竟是如何將事件發送給Observer的:

    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()) {
            observer.onNext(t);
        }
    }

CreateEmmitter的onNext方法非常簡單,就是直接調用了observer.onNext方法,onComplete和onError的原理也和onNext方法大同小異,只不過在onComplete和onError方法中還會調用dispose()方法,這樣在調用onComplete和onError方法之後observer就無法在接收任何事件了。

map操作

我們可以通過map操作來進行數據類型的轉換,map的基本使用方法如下:

    Observable.create(new ObservableOnSubscribe<Integer>() {
        @Override
        public void subscribe(ObservableEmitter<Integer> e) throws Exception {
            e.onNext(new Integer(0));
            e.onComplete();
        }
    }).map(new Function<Integer, String>() {
        @Override
        public String apply(Integer integer) throws Exception {
            return integer.toString();
        }
    }).subscribe(new Observer<String>() {
        public void onSubscribe(Disposable d) { Log.e("RxJava", "onSubscribe");}
        public void onNext(String s) { Log.e("RxJava", "onNext" + s);}
        public void onError(Throwable e) {Log.e("RxJava", "onSubscribe");}
        public void onComplete() {Log.e("RxJava", "onSubscribe");}
    });

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方法其實和create方法很像,只不過這裏返回的是一個ObservableMap對象,並將原來的Observable對象和參數mapper傳入了ObservableMap的構造方法。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);//父類構造方法將source保存在了一個成員變量中
            this.function = function;
        }

        ...
    }    

ObsevableMap的構造方法也只是將原Observable對象和Function對象分別保存在了ObservableMap對象的成員變量source和function中。

由此可見,map方法實際上就是生成了一個ObservableMap對象,並將原來的Observable和參數Function保存在了這個ObservableMap對象中。這個時候我們通過subscribe方法進行訂閱時,實際上是調用的ObservableMap對象的subscribe方法。之前我們分析過,subscribe方法內部又調用了subscribeActual方法,ObservableMap的subscribeActual方法如下:

    public void subscribeActual(Observer<? super U> t) {
        source.subscribe(new MapObserver<T, U>(t, function));
    }

可見subscribeActual方法中調用的還是是原Observable的subscribe方法,只不過subscribe方法中的參數不再是我們最初生成的那個Observer對象,而是對Observer進行了轉換,變成了一個MapObserver對象。當各種事件發出後,接收事件的就變成了這個MapObserver對象,MapObserver對象對onNext方法進行了重寫,MapObserver的源碼如下:

    static final class MapObserver<T, U> extends BasicFuseableObserver<T, U> {
        final Function<? super T, ? extends U> mapper;

        MapObserver(Observer<? super U> actual, Function<? super T, ? extends U> mapper) {
            super(actual);
            this.mapper = mapper;
        }

        @Override
        public void onNext(T t) {
            ...
            U v;

            try {
                v = ObjectHelper.requireNonNull(mapper.apply(t), 
                    "The mapper function returned a null value.");
            } catch (Throwable ex) {
                fail(ex);
                return;
            }
            actual.onNext(v);
        }

        ...
    }

在onNext方法中,傳入的參數T是原數據類型,U是轉換後的數據類型,之後又調用了mapper.apply(t)來實現了數據類型的轉換,這個mapper即我們在調用map方法時傳入的Function對象。最後又直接調用了原Observer的onNext方法,並傳入了轉換後的數據類型,最終完成了map過程。

filter操作

我們也可以通過filter方法來對發射的事件進行過濾,filter方法的基本使用如下:

    Observable.create(new ObservableOnSubscribe<Integer>() {
        @Override
        public void subscribe(ObservableEmitter<Integer> e) throws Exception {
            e.onNext(new Integer(0));
            e.onComplete();
        }
    }).filter(new Predicate<Integer>() {
        @Override
        public boolean test(Integer s) throws Exception {
            return integer.intValue() > 0 ? true : false;
        }
    }).subscribe(observer);

看一下filter方法的源碼:

    public final Observable<T> filter(Predicate<? super T> predicate) {
        ObjectHelper.requireNonNull(predicate, "predicate is null");
        return RxJavaPlugins.onAssembly(new ObservableFilter<T>(this, predicate));
    }

可以看到filter方法的源碼和create方法、map方法非常相似,只不過這次的返回數據有變成了ObservableFilter。可見filter方法和create、map方法的套路基本一致,那我們直接來看ObservableFilter的subscribeActual方法:

    public void subscribeActual(Observer<? super T> s) {
        source.subscribe(new FilterObserver<T>(s, predicate));
    }

與ObservableMap類的subscribeActual方法類似,ObservableFilter類的subscribeActual方法也是直接調用了原Observer的subscribe方法,並傳入了一個FilterObserver對象,參照之前分析map操作時的套路,我們直接看FilterObserver對象的onNext方法:

    public void onNext(T t) {
        if (sourceMode == NONE) {
            boolean b;
            try {
                b = filter.test(t);
            } catch (Throwable e) {
                fail(e);
                return;
            }
            if (b) {
                actual.onNext(t);
            }
        } else {
            actual.onNext(null);
        }
    }

FilterObserver的onNext方法很簡單,直接調用filter.test方法,如果返回true,就調用actual.onNext方法,否則什麼都不做。這樣就實現了事件的過濾。

通過分析RxJava的訂閱流程與map、filter操作符的源碼,我們可以對RxJava的核心思想有一個大致的瞭解,RxJava中的很多其他操作都與map、filter類似,只要掌握了核心思想便不難理解。本文只是對RxJava的原理進行一個簡單的講解,因本人能力有限,如果讀者發現文中有什麼錯誤或不足之處,希望能幫忙指出,大家一起共同進步。

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