为什么在这种情况下处理 DisposableObserver 很重要

6

我正在进行一项与清晰架构相关的Android项目。

我有以下类:

public abstract class RxBaseInteractor<T, Params> {

  private final CompositeDisposable disposables;

  public RxBaseInteractor() {
    this.disposables = new CompositeDisposable();
  }

  abstract public Observable<T> buildUseCaseObservable(Params params);

  public void execute(DisposableObserver<T> observer, Params params) {
    Preconditions.checkNotNull(observer);
    final Observable<T> observable = this.buildUseCaseObservable(params)
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread());
    addDisposable(observable.subscribeWith(observer));
  }

  public void dispose() {
    if (!disposables.isDisposed()) {
      disposables.dispose();
    }
  }

  protected void addDisposable(Disposable disposable) {
    Preconditions.checkNotNull(disposable);
    Preconditions.checkNotNull(disposables);
    disposables.add(disposable);
  }
}

所以execute(..)需要一个DisposableObserver,然后有一个dispose()方法来处理这个observable的释放。

在我的情况中,observable可能是通过retrofit获取WebApi或使用Realm缓存得到的。

现在在presenter的onDestroy()方法中,我调用了interactor.dispose()

 @Override public void destroy() {
        super.destroy();
        myInteractor.dispose();
    }

从视图中调用的函数被称为:
    @Override public void onDestroy() {
    super.onDestroy();
    if (getPresenter() != null) {
      getPresenter().destroy();
    }
  }

我完全理解架构,并且也理解如何处理非托管的网络或数据库资源,但我需要充分理解在这种情况下 observable 的 dispose 是否真的很重要,因为我认为 Retrofit 或 Realm 会自动管理连接并处理它们的资源。
我认为这与处理 realm 或 retrofit 资源无关,但可能与取消订阅可观察对象本身有关。我查看了文档并发现:
DisposableObserver类:一个抽象的Observer,通过实现Disposable来实现异步取消。所有预实现的最终方法都是线程安全的。
使用public dispose()方法在onNext实现中将序列处理完毕后进行处理。
但我仍然不理解使用它的好处。当销毁视图时,它是用于取消订阅可观察对象,以便它从 onNext() 到 onComplete() 并关闭发射器上的订阅吗?
2个回答

16

使用 dispose 方法的原因是,系统在初始化视图 (activityfragment) 后,订阅开始后你决定返回或者启动另一个视图,而旧的订阅仍在执行并且没有完成它的工作。这意味着它仍然在内存中,会导致 内存泄漏。因此,你需要调用 dispose 方法进行取消订阅。


3

除了@abozaid的答案之外,当旧订阅仍处于 On 状态时,并且与此同时,我们的用户切换到其他视图(activityfragment),或关闭旧视图(或 application 本身)时,它肯定会 leak 内存。

但是,如果我们正在使用 AndroidSchedulers.mainThread() 调度器来观察可观测的内容以进行 UI 更新,那么我们的代码将会 崩溃,因为在更新 UI 的时候,viewcontext 将不复存在(或被销毁)。

myObservable.observeOn(AndroidSchedulers.mainThread()) // like this

另一个需要提到的问题是,即使我们通过在代码中采取预防措施来处理崩溃,未使用的subscription 在某个阶段会影响性能


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接