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

时间:2017-11-03 21:58:40

标签: android rx-java observable dispose clean-architecture

我使用干净的架构开发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);
  }
}

所以执行(..)接受一个DisposableObserver,然后调用dispose()方法来处理这个observable。

在我的情况下,observable可能来自WebApi使用Realm进行改造或缓存。

现在在演示者onDestroy()中,我调用了interactor.dispose(),如:

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

在视图之后调用:

    @Override public void onDestroy() {
    super.onDestroy();
    if (getPresenter() != null) {
      getPresenter().destroy();
    }
  }

我完全理解架构,并且我理解处理未管理的网络或数据库资源但我需要完全理解在这种情况下是否真的重要的处置,因为我认为Retrofit或Realm自动管理关闭连接和处置有资源。

我认为这与处置领域或改造资源无关,但它可能与我自己检查文档时自我观察的取消订阅有关,我发现:

  

Class DisposableObserver:一个允许异步取消的抽象Observer   实施Disposable。所有预先实施的最终方法都是   线程安全的。

     

使用public dispose()方法从中处理序列   onNext implementation。

但我仍然不明白使用它的好处。是否可以在销毁视图时取消订阅observable,以便从onNext()转到onComplete()并关闭发射器上的订阅?

2 个答案:

答案 0 :(得分:11)

使用dispose方法背后的原因是因为在系统启动视图(活动或片段)之后。订阅开始然后您决定返回或启动另一个视图,而订阅仍然执行并且没有完成其工作,这意味着它仍然在内存中将导致内存泄漏。因此,您必须调用dispose方法取消订阅。

答案 1 :(得分:2)

在@abozaid的答案中添加更多内容,当较旧的订阅仍为On时,与此同时,我们的用户切换到其他视图(activityfragment)或关闭较旧的视图(或application本身),它肯定会leak的内存。

但是,如果我们使用AndroidSchedulers.mainThread()调度程序观察到 UI更新,则我们的代码将崩溃,因为在更新 UI时viewcontext将会消失(或销毁)。

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

我要补充的一点是,即使我们通过在代码中放置预防措施来处理崩溃,在某个阶段subscription仍未使用的情况下hamper performance