重學Android——Rxjava2.x源碼解析

Rxjava的誕生背景
首先要從異步編程說起,最開始的原生的系統中,如果UI系統處理耗時任務,會引發ANR,所以都是放在子線程做耗時任務,比如網絡請求或者IO操作,再來更新UI界面,這需要在主線程來完成,這樣就涉及到了異步編程。
最開始的異步編程主要有:

  • 使用Java自身提供的Future模型

    • 但這種異步結果獲取比較困難,必須調用Future.get(),回去查看異步是否完成,如果完成,就返回結果,否則繼續等待。當然在JDK8後,提供了completabelFuture,簡化了異步編程
  • Android系統提供的異步模型——AsyncTask。相比於Java提供的方法,此模型無主線程阻塞風險,但是最大的問題是有可能陷入層層嵌套的回調。

Rxjava源碼中鏈式調用
多說也無益,先看源碼。

分析問題時,我們可以從特殊到普通來分析,有時候會有意想不到的效果,所以這次源碼由Single開始分析,我們最簡單的用法:

先在app的gradle中

    implementation "io.reactivex.rxjava2:rxjava:2.2.9"
    implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'

最簡單的實現

        Single.just(1)
                .subscribe(new SingleObserver<Integer>() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onSuccess(Integer integer) {

            }

            @Override
            public void onError(Throwable e) {

            }
        });
    }

這是最簡單的用法,上游發送一個1的事件,下游接到,不牽涉線程切換。
創建被觀察者
我們先直接進Just的源碼

    @CheckReturnValue
    @SchedulerSupport(SchedulerSupport.NONE)
    @NonNull
    public static <T> Single<T> just(final T item) {
        //判空
        ObjectHelper.requireNonNull(item, "item is null");
        //HOOK方法
        return RxJavaPlugins.onAssembly(new SingleJust<T>(item));
    }

第一行,其實看方法名我們也能看出來,是判空的,源碼如下

    public static <T> T requireNonNull(T object, String message) {
        if (object == null) {
            throw new NullPointerException(message);
        }
        return object;
    }

果然不出所料,忽略

第二行,先看外層的RxJavaPlugins.onAssembly,進它的源碼

    /**
     * Calls the associated hook function.
     * @param <T> the value type
     * @param source the hook's input value
     * @return the value returned by the hook
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    @NonNull
    public static <T> Single<T> onAssembly(@NonNull Single<T> source) {
        Function<? super Single, ? extends Single> f = onSingleAssembly;
        if (f != null) {
            return apply(f, source);
        }
        return source;
    }

注意看註釋,說明了這是一個hook方法,可以看到直接return的說是傳入進來的source,所以,我們可以得出,Single.just(item)就相當於new SingleJust<T>(item)。

訂閱過程
再來看.subscribe(new SingleObserver<Integer>)的源碼

   @SchedulerSupport(SchedulerSupport.NONE)
    @Override
    public final void subscribe(SingleObserver<? super T> observer) {
        //判空
        ObjectHelper.requireNonNull(observer, "observer is null");

        //HOOK
        observer = RxJavaPlugins.onSubscribe(this, observer);

        //繼續判空
        ObjectHelper.requireNonNull(observer, "The RxJavaPlugins.onSubscribe hook returned a null SingleObserver. Please check the handler provided to RxJavaPlugins.setOnSingleSubscribe for invalid null returns. Further reading: https://github.com/ReactiveX/RxJava/wiki/Plugins");

        try {
            //執行當前類的subscribeActual
            subscribeActual(observer);
        } catch (NullPointerException ex) {
            throw ex;
        } catch (Throwable ex) {
            Exceptions.throwIfFatal(ex);
            NullPointerException npe = new NullPointerException("subscribeActual failed");
            npe.initCause(ex);
            throw npe;
        }
    }

代碼裏有做註釋,其實真正調用的方法是subscribeActual(observer);方法

protected abstract void subscribeActual(@NonNull SingleObserver<? super T> observer);

可以發現,這是一個抽象方法,那麼我們要找到它的實現。

我們回到來看上面的方法其實可以發現,Single.just()調用的subscribe,而Single.just我們在上面講到,就相當於new SingleJust(),所以我們只要看SingleJust裏的subscribeActual方法就可以了。

public final class SingleJust<T> extends Single<T> {

    final T value;

    public SingleJust(T value) {
        this.value = value;
    }

    @Override
    protected void subscribeActual(SingleObserver<? super T> observer) {
        observer.onSubscribe(Disposables.disposed());
        observer.onSuccess(value);
    }

}

這個類超級簡單,就是把上游的事件發送到下游SingleObserver,比如我們在實例中,Single.just(1)就相當於new SingleJust(1),所以在這兒,value=1,然後調用subscribeActual方法,SingleObserver是一個接口,有三個方法,也是我們回調裏的三個方法

public interface SingleObserver<T> {
    void onSubscribe(@NonNull Disposable d);

    void onSuccess(@NonNull T t);

    void onError(@NonNull Throwable e);
}

在subscribeActual方法中,先observer.onSubscribe(Disposables.disposed());,需要注意的是,這也是just方法獨有的,它直接在onSubscribe方法裏就Disposables.disposed了,這個方法在後面講,這是取消了事件訂閱,因爲它只會發一次,到了這就意味着已經不用訂閱了。然後再調用observer.onSuccess方法,直接把value傳遞了過去。
Map操作符的源碼
再來看增加一個操作符的源碼,就用最常用的map,其實操作符一通百通

        Single.just(1)
                .map(new Function<Integer, Integer>() {
                    @Override
                    public Integer apply(Integer integer) throws Exception {
                        return integer+2;
                    }
                })
                .subscribe(...);

直接看map的源碼

    public final <R> Single<R> map(Function<? super T, ? extends R> mapper) {
        //判空
        ObjectHelper.requireNonNull(mapper, "mapper is null");
        //hook,就相當於new SingleMap
        return RxJavaPlugins.onAssembly(new SingleMap<T, R>(this, mapper));
    }

可以看到,這就相當於new SingleMap(this,mapper);返回值依然是Single

我們看SingleMap的源碼

public final class SingleMap<T, R> extends Single<R> {
    final SingleSource<? extends T> source;

    final Function<? super T, ? extends R> mapper;

    public SingleMap(SingleSource<? extends T> source, Function<? super T, ? extends R> mapper) {
        //這就是剛剛傳進來的this,也就是上游的被觀察者
        this.source = source;
        //這是我們自己在map中寫的new function方法
        this.mapper = mapper;
    }

    //由上文subscribe方法分析可知,當調用subscribe時,這個回調是會被調用的
    @Override
    protected void subscribeActual(final SingleObserver<? super R> t) {
        //可以看到,就是相當於是把上游的被觀察者source,直接調用了它的subscribe方法
        //我們主要的精力只要集中看new MapSingleObserver方法就行
        source.subscribe(new MapSingleObserver<T, R>(t, mapper));
    }

    //此observer觀察者中,把處理後的數據都傳遞給了下游,但是,只提供了事件的流向,因爲事件是在上游產生的
    static final class MapSingleObserver<T, R> implements SingleObserver<T> {

        final SingleObserver<? super R> t;

        final Function<? super T, ? extends R> mapper;

        MapSingleObserver(SingleObserver<? super R> t, Function<? super T, ? extends R> mapper) {
            this.t = t;
            this.mapper = mapper;
        }

        @Override
        public void onSubscribe(Disposable d) {
            t.onSubscribe(d);
        }

        @Override
        public void onSuccess(T value) {
            R v;
            try {
                //外面是判空,相當於就是mapper.apply(value),這個方法其實就是我們自己的map方法
                v = ObjectHelper.requireNonNull(mapper.apply(value), "The mapper function returned a null value.");
            } catch (Throwable e) {
                Exceptions.throwIfFatal(e);
                onError(e);
                return;
            }
            //將map方法處理後的事件,傳遞給下游
            t.onSuccess(v);
        }

        @Override
        public void onError(Throwable e) {
            t.onError(e);
        }
    }
}

看到這兒我們可以發現,事件流向是上游的被觀察者流向觀察者,在操作符中,因爲操作符自身是繼承了被觀察者(在此處爲Single),而在其自身中,有一個內部類是觀察者(在此處爲實現了SingleObserver的MapSingleObserver),事件由上游的被觀察者,流向下游的觀察者,而所有的操作符的結構都是一樣的,每個操作符都只需要給上游操作符提供Observer,並給下游提供一個Observable,內部結構就是,從上游流向下游內部的observer被觀察者,然後此下游的觀察者observable會調用它自己下游的內部observer,這樣,整條鏈就能運行了。
由此可知,Rxjava中,每個操作符內部都實現了一整套PUSH模型的接口體系。
由特殊到普通
現在回到最普通的Rxjava寫法

        Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                emitter.onNext(1);
                emitter.onComplete();
            }
        }).map(new Function<Integer, Integer>() {
            @Override
            public Integer apply(Integer integer) throws Exception {
                return integer+1;
            }
        }).subscribe(new Observer<Integer>() {
            @Override
            public void onSubscribe(Disposable d) {
            }

            @Override
            public void onNext(Integer integer) {
            }

            @Override
            public void onError(Throwable e) {
            }

            @Override
            public void onComplete() {
            }
        });

先看create方法的源碼

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

通過上面的分析,我們一眼可以看出,就相當於new ObservableCreate(source)

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) {
        CreateEmitter<T> parent = new CreateEmitter<T>(observer);//1
        observer.onSubscribe(parent);//2

        try {
            source.subscribe(parent);//3
        } catch (Throwable ex) {
            Exceptions.throwIfFatal(ex);
            parent.onError(ex);
        }
    }
    static final class CreateEmitter<T>
    extends AtomicReference<Disposable>
    implements ObservableEmitter<T>, Disposable {
        ...
    }
    ...
}

這個類比較長,我們先只看我們關心的部分。只以看到我們喜愛的subscribeActual方法,在訂閱時,會調用到此方法。

再來逐句分析,在運行1語句時,new CreateEmitter,看到CreateEmitter的源碼

    //實現了ObservableEmitter,ObservableEmitter是Emitter的子類,用於發射上游數據
    static final class CreateEmitter<T>
    extends AtomicReference<Disposable>
    implements ObservableEmitter<T>, Disposable {

        private static final long serialVersionUID = -3434801548987643227L;

        final Observer<? super T> observer;

        //下游的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()) {
                //把事件傳遞給下游observer,調用觀察者的onNext方法
                observer.onNext(t);
            }
        }
        ...
    }

再回到ObservableCreate的源碼,它是被觀察者Observable的子類,

  • 先在1時new了一個發射器CreateEmitter對象,然後我們把自定義的下游觀察者observer作爲參數傳了進去,這裏同樣也是包裝起來,這個CreateEmitter實現了ObservableEmitter和Disposable接口
  • 在2語句時,觸發我們自定義的observer的onSubscribe(Disposable)方法,實際就是調用觀察者的onSubscribe方法,告訴觀察者已經成功訂閱到被觀察者了;
  • 再執行在語句3,source.subscribe(parent);就和我們分析Map一樣了,就是訂閱,把事件從上游傳到下游。

小結
Observable(被觀察者)和Observer(觀察者)建立連接,也就是訂閱之後,會創建出一個發射器CreateEmitter,發射器會把被觀察者中產生的事件發送到觀察者中,觀察者對發射器中發出的事件做出響應事件。可以看到,訂閱成功之後,Observabel纔會開始發送事件

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