談談對于響應式編程RxJava的理解 - 原理篇

談談對于響應式編程RxJava的理解 - 核心思想篇
談談對于響應式編程RxJava的理解 - 原理篇

源碼分析

我們直接先看一個最簡單的例子

 Observable
        .create(new ObservableOnSubscribe<Object>() {

            @Override
            public void subscribe(ObservableEmitter<Object> e) throws Exception {
                e.onNext("A");

            }
        })
//        .map(new Function<Object, Object>() {
//
//            @Override
//            public Object apply(Object o) throws Exception {
//                return null;
//            }
//        })
       .subscribe(new Observer<Object>() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(Object o) {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onComplete() {

            }
        });

map操作符我們現在先不看,先從最簡單的流程開始,Observable不管用create 創建還是just創建其實內部原理是一樣的,我們這里便于分析RxJava的整個流程所以用了create來創建。根據觀察者模式的概念,我們將RxJava的源碼分析過程從簡單到難,拆分為三步進行:

  • 1、Observer觀察者的創建
  • 2、Observable#create被觀察者的創建
  • 3、subscribe訂閱關系的建立
第一步:Observer觀察者的創建
public interface Observer<T> {

    /**
     * Provides the Observer with the means of cancelling (disposing) the
     * connection (channel) with the Observable in both
     * synchronous (from within {@link #onNext(Object)}) and asynchronous manner.
     * @param d the Disposable instance whose {@link Disposable#dispose()} can
     * be called anytime to cancel the connection
     * @since 2.0
     */
    void onSubscribe(@NonNull Disposable d);

    /**
     * Provides the Observer with a new item to observe.
     * <p>
     * The {@link Observable} may call this method 0 or more times.
     * <p>
     * The {@code Observable} will not call this method again after it calls either {@link #onComplete} or
     * {@link #onError}.
     *
     * @param t
     *          the item emitted by the Observable
     */
    void onNext(@NonNull T t);

    /**
     * Notifies the Observer that the {@link Observable} has experienced an error condition.
     * <p>
     * If the {@link Observable} calls this method, it will not thereafter call {@link #onNext} or
     * {@link #onComplete}.
     *
     * @param e
     *          the exception encountered by the Observable
     */
    void onError(@NonNull Throwable e);

    /**
     * Notifies the Observer that the {@link Observable} has finished sending push-based notifications.
     * <p>
     * The {@link Observable} will not call this method if it calls {@link #onError}.
     */
    void onComplete();

}

Observer其實屬于觀察者模式中的抽象觀察者對象,就是一個接口,里面有onSubscribe開始訂閱回調、onNext拿到事件回調、onError錯誤事件回調、onComplete完成事件回調的抽象方法,我們這里就是new一個這個Observer接口的匿名內部類。

第二步:Observable#create被觀察者的創建

我們先看到Observable.create方法的調用

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

我們點進去RxJavaPlugins.onAssembly看看

  @NonNull
    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;
    }

一開始是一個對onObservableAssembly的判空操作,其實RxJava內部并沒有用到,一開始onObservableAssembly初始化后就是空的,

   setOnObservableAssembly(null);

按我的理解onObservableAssembly是提供給用戶我們自己用的,我們可以重寫
setOnObservableAssembly。例如:

 RxJavaPlugins.setOnObservableAssembly(new Function<Observable, Observable>() {
         @Override
         public Observable apply(Observable observable) throws Exception {

      //例如這里可以加入一下日志打印,可以查看全局哪些地方用到了RxJava
         Log.d("RxJava",observable.toString());
         return observable;
        }
 };

如果要重寫setOnObservableAssembly的話,記得return返回observable,這樣才可以繼續RxJava的整個事件流,不然返回null肯定會報錯的。
這里也不是我們分析的重點,我們再看到return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));這句代碼,我們看到這里返回了一個ObservableCreate對象

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);
        observer.onSubscribe(parent);

        try {
            source.subscribe(parent);
        } catch (Throwable ex) {
            Exceptions.throwIfFatal(ex);
            parent.onError(ex);
        }
    }

ObservableCreate對象是繼承自Observable,的我們先大致看下它的結果,具體先接著看第三步流程,后面再結合起來分析。

第三步:subscribe訂閱關系的建立

直接進入subscribe的源碼

  @SchedulerSupport(SchedulerSupport.NONE)
    @Override
    public final void subscribe(Observer<? super T> observer) {
        ObjectHelper.requireNonNull(observer, "observer is null");
        try {
            observer = RxJavaPlugins.onSubscribe(this, observer);

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

            subscribeActual(observer);
        } catch (NullPointerException e) { // NOPMD
            throw e;
        } catch (Throwable e) {
            Exceptions.throwIfFatal(e);
            // can't call onError because no way to know if a Disposable has been set or not
            // can't call onSubscribe because the call might have set a Subscription already
            RxJavaPlugins.onError(e);

            NullPointerException npe = new NullPointerException("Actually not, but can't throw other exceptions due to RS");
            npe.initCause(e);
            throw npe;
        }
    }

subscribe方法里傳進來的就是我們自定義的observer(就是自己寫的匿名類),前面也是一些初始化和判空操作,我們主要看 subscribeActual(observer);這句代碼。我們點進去發現是Observable里的一個抽象方法

protected abstract void subscribeActual(Observer<? super T> observer);

我們從第二步可以知道ObservableCreate對象是繼承自Observable的,所以這里抽象方法subscribeActual的實現就是在ObservableCreate里,我們看到ObservableCreate里的subscribeActual方法

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

一開始將我們傳進來的observer包裝成一個發射器CreateEmitter對象parent,再調用觀察者的observer.onSubscribe(parent);這里實現onSubscribe方法的實際上就是我們自己寫的內部類里的onSubscribe方法,
image.png

我們看到onSubscribe方法里最終我們調用了發射器CreateEmitter的onNext方法,所以我們進去onNext方法看看

 @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(t);
            }
        }

我們看到發射器里的onNext方法就是最終調用到我們自定義觀察者observer的
onNext方法。

至此,RxJava最簡單的訂閱關系和收發數據的流程就通了,我們再通過一張簡易的流程圖總結下流程。

image.png

那么現在我們再加入map操作符一起分析看看

Map操作符原理分析

我們對上面的代碼進行簡單的修改,并且加入map操作符
注意看代碼注釋

 Observable
        //ObservableCreate   將自定義source傳進去
        .create(
          //自定義被觀察者(起點)
          new ObservableOnSubscribe<String>() {

            @Override
            public void subscribe(ObservableEmitter<String> e) throws Exception {
                e.onNext("A");

            }
        })
        //ObservableCreate.map
        .map(new Function<String, Bitmap>() {

            @Override
            public Bitmap apply(String o) throws Exception {
                return null;
            }
        })
        //ObservableMap.subscribe
       .subscribe(
           //自定義觀察者(終點)
           new Observer<Object>() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(Object o) {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onComplete() {

            }
        });

map.png

其實上面map操作符的作用就是從Observable起點開始,通過map操作符將String類型數據轉化為Bitmap類型數據最后流向終點Observer。
經過之前的分析,我們已經知道Observable. create返回了一個ObservableCreate對象,這時我們如果再調用map操作符的話,就是對ObservableCreate進行了.map的操作了。

   @CheckReturnValue
    @SchedulerSupport(SchedulerSupport.NONE)
    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,所以上面整個程序的最后一步調用會走到ObservableMap.subscribe。(具體可以看我代碼的注釋)

因為有前面的分析基礎,現在我們直接進入subscribe訂閱流程的代碼

 @SchedulerSupport(SchedulerSupport.NONE)
    @Override
    public final void subscribe(Observer<? super T> observer) {
        ObjectHelper.requireNonNull(observer, "observer is null");
        try {
            observer = RxJavaPlugins.onSubscribe(this, observer);

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

            subscribeActual(observer);
        } catch (NullPointerException e) { // NOPMD
            throw e;
        } catch (Throwable e) {
            Exceptions.throwIfFatal(e);
            // can't call onError because no way to know if a Disposable has been set or not
            // can't call onSubscribe because the call might have set a Subscription already
            RxJavaPlugins.onError(e);

            NullPointerException npe = new NullPointerException("Actually not, but can't throw other exceptions due to RS");
            npe.initCause(e);
            throw npe;
        }
    }

因為我們加入了map操作符,現在這里的subscribeActual(observer);就是調用的
ObservableMap的subscribeActual了,


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

這里,源碼將自定義觀察者Observer(終點),傳入到MapObserver對象里,將自定義觀察者Observer包裝了一層,new了一個MapObserver對象出來。
而這里的 source.subscribe里的source就是上一層的Observable也就是ObservableCreate,所以這里調用了ObservableCreate的subscribe方法。因為不管是ObservableMap還是ObservableCreate都是繼承自Observable
所以我們再進入Observable的subscribe方法


@SchedulerSupport(SchedulerSupport.NONE)
    @Override
    public final void subscribe(Observer<? super T> observer) {
        ObjectHelper.requireNonNull(observer, "observer is null");
        try {
            observer = RxJavaPlugins.onSubscribe(this, observer);

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

            subscribeActual(observer);
        } catch (NullPointerException e) { // NOPMD
            throw e;
        } catch (Throwable e) {
            Exceptions.throwIfFatal(e);
            // can't call onError because no way to know if a Disposable has been set or not
            // can't call onSubscribe because the call might have set a Subscription already
            RxJavaPlugins.onError(e);

            NullPointerException npe = new NullPointerException("Actually not, but can't throw other exceptions due to RS");
            npe.initCause(e);
            throw npe;
        }
    }

而這次 subscribeActual(observer);調用的是ObservableCreate的subscribeActual了,而且這次的observer觀察者是自定義觀察者經過包裝之后的MapObserver對象,


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

observer.onSubscribe(parent);就是調用了我們自定義觀察者(終點的)的onSubscribe, source.subscribe(parent);這句調用的就是自定義被觀察者(起點)的subscribe方法,也就是我們上面流程分析的CreateEmitter發射器的onNext方法,

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

而此時的observer.onNext(t);的onNext方法不再是自定義observer的onNext方法了,而是先調用MapObserver的onNext方法

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

        @Override
        public void onNext(T t) {
            if (done) {
                return;
            }

            if (sourceMode != NONE) {
                actual.onNext(null);
                return;
            }

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

而這一句代碼 v = ObjectHelper.requireNonNull(mapper.apply(t), "The mapper function returned a null value.");就是真正執行變化的代碼,也就是我們自己重寫的map的apply方法里,最后再調用actual.onNext(v);方法返回整個終點的onNext(v);,到此執行完整個事件流。還是和之前一樣,我再用一張流程圖總結下。


image.png

其實總結一下:RxJava整個事件流的流程就是將事件通過ObservableMap=>ObservableCreate=> CreateEmitter層層包裝包裝(你的業務需要幾個操作符就幾層包裝),再通過CreateEmitter#onNext=>ObserverMap#onNext像洋蔥一樣一層層拆開包裝,最后返回到終點響應事件也就是我們自定義的Observer的過程。這也是整個RxJava的核心思想,RxJava里所有的操作符的思路都是這樣的執行流程。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。