从我在源代码中看到的,在实现方面的区别在于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)
关键区别在于,实现可以随时更改,并且更改会导致当前一次性的处置。
“MutableDisposable 是可以随时更改其实现的一次性产品。更改一次性实现的行为会导致当前的一次性产品被处置。”