1. 程式人生 > >Rxjava關於Disposable你應該知道的事

Rxjava關於Disposable你應該知道的事

相關文章:Rxjava關於Disposable你應該知道的事

Composite  [kəmˈpɑ:zət] 

adj.混合成的,綜合成的;[建]綜合式的;[數]可分解的;[植]菊科的
n.合成物,混合物,複合材料;[植]菊科植物

disposable   [dɪˈspoʊzəbl] 

adj.一次性的,可任意處理的;用後就拋棄的;免洗的;可供使用的
n.〈美口〉使用後隨即拋掉的東西(尤指容器等)

關於disposable

Disposable類

  • dispose():主動解除訂閱
  • isDisposed():查詢是否解除訂閱 true 代表 已經解除訂閱

rxjava雖然好用,但是總所周知,容易遭層記憶體洩漏。也就說在訂閱了事件後沒有及時取閱,導致在activity或者fragment銷燬後仍然佔用著記憶體,無法釋放。而disposable便是這個訂閱事件,可以用來取消訂閱。但是在什麼時候取消訂閱呢?我知道有兩種方式:

  • 使用CompositeDisposable
    看原始碼,CompositeDisposable的介紹很簡單

A disposable container that can hold onto multiple other disposables and offers O(1) add and removal complexity.

一個disposable的容器,可以容納多個disposable,新增和去除的複雜度為O(1)。
這裡需要注意的是在該類的addAll方法有這麼一句註釋

Atomically adds the given array of Disposables to the container or disposes them all if the container has been disposed

也就是說,如果這個CompositeDisposable容器已經是處於dispose的狀態,那麼所有加進來的disposable都會被自動切斷。

所以說可以建立一個BaseActivity,用CompositeDisposable來管理訂閱事件disposable,然後在acivity銷燬的時候,呼叫compositeDisposable.dispose()就可以切斷所有訂閱事件,防止記憶體洩漏。

CompositeDisposable類

1、可以快速解除所有新增的Disposable類.
2、每當我們得到一個Disposable時就呼叫CompositeDisposable.add()將它新增到容器中, 在退出的時候, 呼叫CompositeDisposable.clear() 即可快速解除.

案例程式碼如下:

CompositeDisposable compositeDisposable=new CompositeDisposable();
Observable.create(new ObservableOnSubscribe<Integer>() {
          @Override
          public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
              emitter.onNext(1);
              emitter.onComplete();或者 emitter.onError(new Throwable("O__O "));
          }
      }).subscribe(new Observer<Integer>() {
          private Disposable mDisposable;
          @Override
          public void onSubscribe(Disposable d) {
              <!-- 訂閱   -->
              mDisposable = d;
              <!-- 新增到容器中 -->
              compositeDisposable.add(d);
          }
          @Override
          public void onNext(Integer value) {
        <!-- 判斷mDisposable.isDisposed()如果解除了則不需要處理 -->
          }
          @Override
          public void onError(Throwable e) {
          }
          @Override
          public void onComplete() {
          }
      });
      <!-- 解除所有訂閱者 -->
compositeDisposable.clear();
  • 在oError和onComplete後呼叫disposable.dispose();,也就是上面我給的例子中的方法。
    檢視原始碼,ObservableCreate的靜態類CreateEmitter就是這種方式實現的。同時也可以看到,onError和onComplete不可以同時呼叫的原因:每次掉用過onError或onComplete其中一個方法後,就會掉用dispose()方法,此時訂閱取消,自然也就不能掉用另一個方法了
new Observer<Integer>() {
          private Disposable mDisposable;
          private int i;

          @Override
          public void onSubscribe(Disposable d) {
              Log.d(TAG, "subscribe");
              mDisposable = d;
          }

          @Override
          public void onNext(Integer value) {
              Log.d(TAG, "onNext: " + value);
              i++;
              if (i == 2) {
                  Log.d(TAG, "dispose");
                  mDisposable.dispose();
                  Log.d(TAG, "isDisposed : " + mDisposable.isDisposed());
              }
          }

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

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