Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is disposing DisposableObserver is important in this case

I working on android project with clean architecture.

I have the below class:

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);
  }
}

So execute(..) take a DisposableObserver and then there is a dispose() method which is called to dispose this observable.

In my case the observable may come from WebApi using retrofit or cache using Realm.

Now in the presenter onDestroy(), i called the interactor.dispose() like:

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

which is called after that from the view:

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

I fully understanding the architecture and also i understand disposing un-managed network or database resources but i need to fully understand if in this case the dispose of observable really matter as i thought that Retrofit or Realm auto manage closing a connections and disposing there resources.

I think it's not related to dispose realm or retrofit resources but it may be related to unsubscribe on the observable it self as i checked the documentation and i found :

Class DisposableObserver: An abstract Observer that allows asynchronous cancellation by implementing Disposable. All pre-implemented final methods are thread-safe.

Use the public dispose() method to dispose the sequence from within an onNext implementation.

But i still not understand the benefits of using it. Is it for unsubscribe from the observable when destroying the view so it will go from onNext() to onComplete() and close the subscription on the emitter?

like image 649
Marzouk Avatar asked Nov 03 '17 21:11

Marzouk


People also ask

How do you dispose of observables?

It is good practice to dispose complete observable chain running in your Activity or Fragment Life-Cycle. A typical example of disposing an Observable: In above example, you can see that in doTask() method, disposable is added to CompositeDisposable and in onStop observable is disposed using compositeDisposable.

What is DisposableObserver?

An abstract Observer that allows asynchronous cancellation by implementing Disposable . All pre-implemented final methods are thread-safe. Use the public dispose() method to dispose the sequence from within an onNext implementation. Like all other consumers, DisposableObserver can be subscribed only once.


2 Answers

The reason behind using dispose method is because after the system initiate the view (activity or fragment), the subscription gets start and then you have decided to go back or initiate another view while the older subscription is still getting executed and didn't finish its job. This means that it's still in the memory which will cause a memory leak. So you have to call dispose method for unsubscribe.

like image 178
abozaid Avatar answered Nov 15 '22 06:11

abozaid


Adding more to @abozaid's answer, When older subscription is still On and in the meantime, our user switches to other view (activity or fragment) or closes older view (or application itself), it'll definitely leak memory.

But, if we were observing observable for UI updation with AndroidSchedulers.mainThread() scheduler, then our code would crash because at the time of updating UI, the view and context would have gone away (or destroyed).

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

One other point, I can add here is that, even if we handle the crash by putting precaution in code, the subscription running unused would hamper performance at some stage.

like image 41
Kushal Avatar answered Nov 15 '22 08:11

Kushal