jeremy303
jeremy303

Reputation: 9241

Best practice for disposing Completable, Single, Maybe and terminating Observables in RxJava

I'm asking this from an Android perspective, but this should apply to RxJava in general.

As a best practice, should my view always dispose of even short lived Completable, Single, Maybe and terminating Observable Rx types that should terminate in short order, but could be still be executing when the user closes the view? I'm aware that when the Rx chain terminates, it is disposed but this could potentially occur sometime after the view is closed.

For example, a Single that's performing an HTTP GET. The call will complete, but it may be after the view destroyed, temporarily preventing garbage collection.

And if a CompositeDisposable is used to collect such Disposables in a long-lived view, I would think that care should be taken to clear() or otherwise remove these Disposables regularly to prevent unbounded growth in the size of CompositeDisposable?

Upvotes: 29

Views: 19166

Answers (4)

Sheng-Fang
Sheng-Fang

Reputation: 21

I have similar issue as well, sometime task can be disposed but sometime are not, which cause app crash randomly. However, everything get work after I update rxJava/Rxandroid version.

Original Rx version:

implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
implementation 'io.reactivex.rxjava2:rxjava:2.1.5'

And then upgrade to

implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
implementation 'io.reactivex.rxjava2:rxjava:2.2.6'

Upvotes: 0

Fakhriddin Abdullaev
Fakhriddin Abdullaev

Reputation: 4910

// 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(); 

call clear in onResume

use dispose in onDestroy

Upvotes: 2

Jon
Jon

Reputation: 1763

As a best practice, should my view always dispose of even short lived Completable, Single, Maybe and terminating Observable Rx types

If you're sharing the code with others, as a best practice, I am going to say yes you should dispose. While it may seem like extra boiler plate, it will prevent the next developer from trying to hook into the your subscription code and attempt to access components that may no longer exist (ie a Context after a Fragment is detached... etc).

And if a CompositeDisposable is used to collect such Disposables in a long-lived view, I would think that care should be taken to clear() or otherwise remove these Disposables regularly to prevent unbounded growth in the size of CompositeDisposable?

I do want to point out that in rxjava2, CompositeDisposables have a state; once you call dispose(), any subsequent Disposable added will be immediately disposed of. So as a best practice:

  1. create a fresh CompositeDisposable at the beginning of the lifecycle (onCreate(...) etc)
  2. take care of dispose() in onDestroy(...) because by that point your callback practically has no value and is just holding onto resources.

Upvotes: 12

Benjamin
Benjamin

Reputation: 7368

It's a good practice to dispose CompositeDisposable in onPause or onDestroy to avoid such problems.

Upvotes: 5

Related Questions