關於Rxjava個人的一些理解

       Android開發中,有一個框架Rxjava大家做過android開發的應該都比較熟悉了,它是一個異步響應框架,能夠快速在主線程和其它線程之間進行切換,並且在處理比較複雜的邏輯時候依然能夠清晰地展示其操作邏輯,所以在開發過程中經常使用到,下面我就簡單講下Rxjava的一些個人理解。

    Rxjava使用:

//創建Observable對象,實現subscribe回調

      Observable observable=Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                emitter.onNext("xxx");//Observer onNext回調的實現
                emitter.onNext("xxx");
                emitter.onComplete();//Observer onNext回調的實現
            }
        });

//創建Observer對象

Observer<String> observer=new Observer<String>() {
            @Override
            public void onSubscribe(Disposable d) {
                Log.e(TAG,"onSubscribe");
            }

            @Override
            public void onNext(String value) {
                Log.e(TAG,"onNext:"+value);
            }

            @Override
            public void onError(Throwable e) {
                Log.e(TAG,"onError="+e.getMessage());
            }

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

//實現訂閱關係

       observable.subscribe(observer);
注:這裏通過被觀察者訂閱觀察者的方式實現了兩者的關聯,這樣在被觀察者中調用onNext,onComplete等方法時候,值就被傳遞到觀察者響應的回調方法中去了。


上面說到的是舊的實現方式,現在一般都改爲了鏈式調用方法,如下:

Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                emitter.onNext("xxx");//Observer onNext回調的實現
                emitter.onNext("xxx");
                emitter.onComplete();//Observer onNext回調的實現
            }
        }).subscribe(new Observer<String>() {
            @Override
            public void onSubscribe(Disposable d) {
                Log.e(TAG,"onSubscribe");
            }

            @Override
            public void onNext(String value) {
                Log.e(TAG,"onNext:"+value);
            }

            @Override
            public void onError(Throwable e) {
                Log.e(TAG,"onError="+e.getMessage());
            }

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

通過對比就很容易發現,鏈式調用其實就是舊方式調用的組合

那麼如何快速切換主線程與其他線程了,這裏就需要使用到SchedulersAndroidSchedules了,具體使用如下:

.SubcribleOn(Schedulers.io())   被觀察者中的操作在子線程操作

.ObserveOn(AndroidSchedules.mainThread())   觀察者中操作在主線程中操作

結合上面代碼使用,如下:

Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                emitter.onNext("xxx");//Observer onNext回調的實現
                emitter.onNext("xxx");
                emitter.onComplete();//Observer onNext回調的實現
            }
        }) .subscribeOn(Schedulers.io())
           .observeOn(AndroidSchedulers.mainThread())
           .subscribe(new Observer<String>() {
            @Override
            public void onSubscribe(Disposable d) {
                Log.e(TAG,"onSubscribe");
            }

            @Override
            public void onNext(String value) {
                Log.e(TAG,"onNext:"+value);
            }

            @Override
            public void onError(Throwable e) {
                Log.e(TAG,"onError="+e.getMessage());
            }

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

從上面的代碼可以看得到當我在被觀察者Observable中調用onNext和onComplete方法後,觀察者Observer中就會在相應方法中立即得到相應,這就是響應式的方法,至於異步就是上面說的主線程與其他線程的切換,這樣Rxjava還可以代替Handler和AsynTask進行相應操作。

  那麼他們到底是如何實現這個訂閱關係的呢,這還需要從源碼的方面分析下:

/** 
  * 創建被觀察者(Observable)的創建和發送信息給觀察者,對應最上面使用方式裏面舊方法的第一步操作
  **/

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

            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                emitter.onNext("xxx");
                emitter.onNext("xxx");
                emitter.onComplete();
            }
        })

/** 
  * 源碼分析:Observable.create(new ObservableOnSubscribe<Integer>(){...})
  **/
    public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {

    ...
      // 僅貼出關鍵源碼

      return new ObservableCreate<T>(source);
      // 創建ObservableCreate類對象 ->>分析1
    // 注:傳入source對象(即 我們手動創建的ObservableOnSubscribe對象)  
    }


  /** 
    * 分析1:new ObservableCreate<T>(source)
    **/

    public final class ObservableCreate<T> extends Observable<T> {
  // ObservableCreate類 = Observable的子類 

      ...
      // 僅貼出關鍵源碼

        final ObservableOnSubscribe<T> source;

        // 構造函數
      // 傳入了傳入source對象 = 手動創建的ObservableOnSubscribe對象
        public ObservableCreate(ObservableOnSubscribe<T> source) {
            this.source = source;
        }
        
    /** 
      * 重點關注:複寫了subscribeActual()
      * 作用:訂閱時,通過接口回調 調用被觀察者(Observerable) 與 觀察者(Observer)的方法
      **/
        @Override
        protected void subscribeActual(Observer<? super T> observer) {

              // 1. 創建1個CreateEmitter對象(封裝成1個Disposable對象)
          // 作用:發射事件
            CreateEmitter<T> parent = new CreateEmitter<T>(observer);

            // 2. 調用觀察者(Observer)的onSubscribe()
            // onSubscribe()的實現 = 使用步驟2(創建觀察者(Observer))時複寫的onSubscribe()
            observer.onSubscribe(parent);

            try {
                // 3. 調用source對象的subscribe()
                // source對象 = 使用步驟1(創建被觀察者(Observable))中創建的ObservableOnSubscribe對象 
                // subscribe()的實現 = 使用步驟1(創建被觀察者(Observable))中複寫的subscribe()->>分析2
                source.subscribe(parent);

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

  /** 
    * 分析2:emitter.onNext("1");
    * 此處僅講解subscribe()實現中的onNext()
    * onError()、onComplete()類似,此處不作過多描述
    **/
    static final class CreateEmitter<T> extends AtomicReference<Disposable>
                                        implements ObservableEmitter<T>, Disposable {

        ...
        // 僅貼出關鍵代碼

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

            // 若無斷開連接(調用Disposable.dispose()),則調用觀察者(Observer)的同名方法 = onNext()
            // 觀察者的onNext()的內容 = 使用步驟2中複寫內容
            if (!isDisposed()) {
                observer.onNext(t);
            }
        }
 // onError()、onComplete()類似,此處不作過多描述
        // 特別說明:調用該2方法,最終都會自動調用dispose(),即斷開觀察者 & 被觀察者的連接
        @Override
        public void onError(Throwable t) {
            if (t == null) {
                t = new NullPointerException("onError called with null. Null values are generally not allowed in 2.x operators and sources.");
            }
            if (!isDisposed()) {
                try {
                    observer.onError(t);
                } finally {
                    dispose();
                }
            } else {
                RxJavaPlugins.onError(t);
            }
        }

        @Override
        public void onComplete() {
            if (!isDisposed()) {
                try {
                    observer.onComplete();
                } finally {
                    dispose();
                }
            }
        }

從上面的源碼中可以看到調用emitter.onNext方法和onComplete方法最終都調用到Observer中的onNext和onComplete中去

接下來就是訂閱的實現:

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

            @Override
            public void onNext(String value) {
                Log.e(TAG,"onNext:"+value);
            }

            @Override
            public void onError(Throwable e) {
                Log.e(TAG,"onError="+e.getMessage());
            }

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

/** 
  * 源碼分析:Observer類
  **/
  public interface Observer<T> {
      // 注:Observer本質 = 1個接口

      // 接口內含4個方法,分別用於 響應 對應於被觀察者發送的不同事件
        void onSubscribe(@NonNull Disposable d); // 內部參數:Disposable 對象,可結束事件
        void onNext(@NonNull T t);
        void onError(@NonNull Throwable e);
        void onComplete();
    }

/** 
  * 特別說明:Subscriber類
  * 定義:RxJava 內置的一個實現了 Observer 的抽象類
  * 作用:擴展Observer 接口 = 新增了2個方法 = 
  *      1. onStart():在還未響應事件前調用,用於初始化工作
  *      2. unsubscribe():用於取消訂閱。在該方法被調用後,觀察者將不再接收 & 響應事件
  *      注:調用該方法前,先使用 isUnsubscribed() 判斷狀態,確定被觀察者Observable是否還持有觀察者Subscriber的引用;若引用不能及時釋放,就會出現內存泄露
  * 使用方式:與Observer使用幾乎相同(實質上,Observer總是會先被轉換成Subscriber再使用)
  **/
  Subscriber<String> subscriber = new Subscriber<Integer>() {

            @Override
            public void onSubscribe(Subscription s) {
                Log.d(TAG, "開始採用subscribe連接");
            }

            @Override
            public void onNext(Integer value) {
                Log.d(TAG, "對Next事件作出響應" + value);
            }

            @Override
            public void onError(Throwable e) {
                Log.d(TAG, "對Error事件作出響應");
            }

            @Override
            public void onComplete() {
                Log.d(TAG, "對Complete事件作出響應");
            }
        };


/** 
  * 源碼分析:Observable.subscribe(observer)
  * 說明:該方法屬於 Observable 類的方法(注:傳入1個 Observer 對象)
  **/  

  @Override
  public final void subscribe(Observer<? super T> observer) {

    ...
    // 僅貼出關鍵源碼
   
    subscribeActual(observer);
    // 繼續往下看:分析1

  }

/** 
  * Observable.subscribeActual(observer)
  * 說明:屬於抽象方法,由子類實現;此處的子類 = 步驟1創建被觀察者(Observable)時創建的ObservableCreate類
  * 即 在訂閱時,實際上是調用了步驟1創建被觀察者(Observable)時創建的ObservableCreate類裏的subscribeActual()
  * 此時,你應該回頭看上面的步驟1裏的subscribeActual(),應該能理解RxJava的整個訂閱流程了。
  **/
  protected abstract void subscribeActual(Observer<? super T> observer);

在這裏就可以看到訂閱實際上從源碼角度看又回到創建Observable時候ObservableCreate類,並將Observer對象傳遞過去,這樣在Observable中調用onNext等方法,實際上是調到了Observer中相應方法中去了。現實中關於Rxjava的使用在應用開發的過程中基本上都會使用到,現在一種比較好的結合使用方式是Retrofit+mvp+Rxjava(Retrofit可以添加Rxava作爲適配器,而MVP開發模式可以很好地將UI和邏輯區分),這裏不做講解。

以上是個人對Rxjava的一些認識,寫的比較簡單,各位如果有什麼好的建議,可以提出,本人將虛心接受。
                

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