When to call dispose and clear on CompositeDisposable
Asked Answered
I

4

67

My question can be a duplicate of How to use CompositeDisposable of RxJava 2? But asking to clear one more doubt. According to the accepted answer

// Using clear will clear all, but can accept new disposable
disposables.clear(); 
// Using dispose will clear all and set isDisposed = true, so it will not accept any new disposable
disposables.dispose(); 

In my case, I'm using fragments as my views (View layer in MVP) and in some scenarios, I add active fragment to backstack, which actually does not kill the Fragment but only its view. Which means only onDestroyView is called and not the onDestroy . And later I can come back to the same fragment which is in the backstack, so only its view is being re-created. I have a CompositeDisposable as the member of my BaseFragment which holds subscriptions.

My question is, should I call clear on CompositeDisposable each time on onDestroyView? So that it can again take subscriptions once the view is resumed? And call dispose on the onDestroy, so that when the fragment itself is destroyed no need to take disposables anymore?

If it is wrong what is the proper way to handle. When clear and dispose have to be called.?

Inference answered 1/11, 2017 at 15:6 Comment(1)
I don't understand why you would ever call dispose over clear. The only difference is it will automatically dispose any future observables added to it. Can't personally think of a usecase for this although I'm sure there are plenty...Guizot
C
25

You're right, you can save yourself from creating a new CompositeDisposable for each time the corresponding view is created, but instead treat a CompositeDisposable as a single instance tied to the onCreate/onDestroy lifecycle methods and treat aggregated disposables as part of the fragment view calling clear in onDestroyView.

Cymoid answered 1/11, 2017 at 17:58 Comment(0)
L
15

Instead of using CompositeDisposable.dispose(), you can better use CompositeDisposable.clear() so you don't have to create a new CompositeDisposable: method documentation.

clear() //Atomically clears the container, then disposes all the previously contained Disposables.

dispose() //Dispose the resource, the operation should be idempotent.
Legging answered 12/2, 2020 at 5:56 Comment(0)
R
9
private final CompositeDisposable disposables = new CompositeDisposable();


// adding an Observable to the disposable
disposables.add(sampleObservable()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeWith(new DisposableObserver<String>() {
                    @Override
                    public void onComplete() {
                    }

                    @Override
                    public void onError(Throwable e) {
                    }

                    @Override
                    public void onNext(String value) {
                    }
                }));

    static Observable<String> sampleObservable() {
        return Observable.defer(new Callable<ObservableSource<? extends String>>() {
            @Override
            public ObservableSource<? extends String> call() throws Exception {
                // Do some long running operation
                SystemClock.sleep(2000);
                return Observable.just("one", "two", "three", "four", "five");
            }
        });
    }                


// Using clear will clear all, but can accept new disposable
disposables.clear(); 
// Using dispose will clear all and set isDisposed = true, so it will not accept any new disposable
disposables.dispose(); 
  • Clear - onStop()
  • Dispose - onDestroy()

I have created a sample project to demonstrate the use of RxJava2. Here you can find the sample project - RxJava2-Android-Samples

Rapture answered 7/3, 2019 at 15:42 Comment(1)
Hello, do you happen to know how I can fix my issue :#57598776 ( it's based off of your library )Tapia
P
0

I faced same issue. I fixed it with the following method BaseAbstractPresenter:

  protected lateinit var compositeDisposable : CompositeDisposable

@CallSuper
override fun attachView(view: BaseView) {
    compositeDisposable = CompositeDisposable()
}

@CallSuper
override fun detachView() {
    if(this::compositeDisposable.isInitialized)
        compositeDisposable.dispose()
}
Ploch answered 3/11, 2022 at 7:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.