DisposableObservable vs.(Regular)Observable

时间:2017-01-08 05:38:47

标签: java rx-java

从我在源代码中看到的,实现方面的差异是-f实现了DisposableObserver接口。

Disposable内,它调用一个自我处理的辅助函数。

dispose

但实际上,两者之间有什么区别。一旦不再需要,它就不会成为常规的Observable垃圾吗?

@Override public final void dispose() { DisposableHelper.dispose(s); } 使用DisposableObservable的默认用例是什么?

2 个答案:

答案 0 :(得分:4)

主要是为了避免内存泄漏,因为它使您可以随时取消订阅。可能发生以下情况:拥有订阅对象的对象在其生命周期的尽头,而订阅正在执行一些繁重的工作,而这需要更多时间。在这种情况下,订阅将保留在内存中,从而泄漏拥有它的对象。为避免这种情况,您可以存储订阅的返回值(一次性),并在所有者对象的生命周期结束时稍后调用dispose。通常,人们最终将每种一次性用品添加到CompositeDisposable(基本上是一袋一次性用品)中,然后将它们与CompositeDisposable.clear()一起清除,这样就不必跟踪每个一次性用品

假设您有一个名为ItemPublisher的类,它提供了无限的事件流:

class ItemPublisher {
  // ...

  public Flowable<Item> getItemsStream() {
    // ...
  }
}

现在,假设您有一个名为ItemHandler的类可以订阅该流:

class ItemHandler {
  // ...

  public void observeItems() {

    itemPublisher.getItemsStream()
      .subscribe(
        // handle onNext events,
        // handle onError events
        // infinite stream, so we don't need to handle onComplete
      );
  }
}

因此,您的软件正在运行,一切都很好。在某个时刻,您的ItemHandler实例将达到其生命周期的尽头。该实例应该被销毁。但是,由于我们在这里处理Observer模式,因此ItemPublisher保留了对ItemHandler实例的隐式引用,该引用是在您调用subscribe方法时传递给它的。由于流是无限的,因此该引用将永远不会被删除,从而阻止GC清理ItemHandler实例,从而导致内存泄漏。仅无限流不会发生这种情况:如果ItemPublisher的寿命比ItemHandler长,则同样会发生。

这就是为什么我们有Disposable接口。调用subscribe时,可以使用返回Disposable的方法的重载版本。当您不再需要订阅时,可以在其上调用dispose()。因此,在我们的示例中:

class ItemHandler {
  private Disposable subscriber;  // this gets initialized somewhere

  // ...

  public void observeItems() {

    itemPublisher.getItemsStream()
      .subscribe(this.getSubscriber());
  }


  // later, when you know that this ItemHandler instance is not needed anymore
  public void wrapItUp() {
    // ...
    subscriber.dispose();
  }
}

如前所述,您还拥有CompositeDisposable,当您有很多订阅时,它会派上用场。通过使用它,您可以将所有订阅收集到一个位置,然后立即将其全部删除。例如:

class ItemHandler {
  private CompositeDisposable disposables;

  // ...

  public void observeItems() {

    disposables.add(itemPublisher.getItemsStream()
      .subscribe(
        // ...
      )
    );
  }


  public void observeSomethingElse() {
     disposables.add(somethingElse.getStreamOfSomethingElse()
      .subscribe(
        // ...
      )
    );
  }

  // later, when you know that this ItemHandler instance is not needed anymore
  public void wrapItUp() {
    // ...
    disposables.clear();
  }
}

答案 1 :(得分:3)

关键的区别在于,可以随时更改实施,并且更改会导致处理当前的一次性用品。

&#34; MutableDisposable是一种可随时更改其实现的一次性用品。改变一次性实施的行为导致当前的一次性处置。&#34;