DisposableObserver与(常规)观察者

thy*_*all 6 java rx-java

从我在源代码中看到的,在实现方面的区别在于DisposableObserver实现Disposable接口。

在内部dispose,它调用一个自动处理的助手函数。

@Override
public final void dispose() {
    DisposableHelper.dispose(s);
}
Run Code Online (Sandbox Code Playgroud)

但实际上,两者之间有什么区别。不再需要不再收集常规可观察的垃圾了吗?

使用DisposableObserverover 的默认用例是Observer什么?

Ric*_*ira 12

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

假设您有一个ItemPublisher提供无限事件流的类:

class ItemPublisher {
  // ...

  public Flowable<Item> getItemsStream() {
    // ...
  }
}
Run Code Online (Sandbox Code Playgroud)

现在,假设您有一个名为的类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
      );
  }
}
Run Code Online (Sandbox Code Playgroud)

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

这就是为什么我们有Disposable接口。调用时subscribe,您可以使用返回 a 的方法的重载版本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();
  }
}
Run Code Online (Sandbox Code Playgroud)

正如我之前提到的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();
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 别担心,我不是为了赏金:P 很高兴我能提供帮助! (4认同)

Mui*_*rik 3

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

“MutableDisposable 是可以随时更改其实现的一次性产品。更改一次性实现的行为会导致当前的一次性产品被处置。”