Managing Disposables in RxJava 2 — The Less Bad Version

Cody Engel
The Kotlin Chronicle
3 min readDec 6, 2018

--

I wrote an article about managing disposables back in 2017. This was my first stab at trying to work with the new callbacks and wanting to create a boiler-plate free way to work with them. I made a rather glaring mistake though, the entire fictitious application has a single CompositeDisposable which means when one controller is destroyed it would try dispose which will prematurely dispose all of your streams. Yikes, that’s definitely not a good idea. The article spawned a lot of great discussion and I didn’t see much reason to provide an update, if you check the comments section then you’ll quickly know it’s a bad idea after-all. Unfortunately that article started ranking really well on Google (it’s now number one for the query managing disposables or composite disposable and is one of my most viewed articles on Medium); it’s time to provide alternative solutions.

Photo by Bas Emmen

Scoping Disposables Is Important

Unless you want bad things to happen it’s important that your disposables aren’t globally scoped and you can dispose of some without disposing of everything. In the Android world I’ve found that having one CompositeDisposable per view controller (Activity/Fragment) as well as one per ViewModel seems to work out fairly well. This means we want something that looks something like this…

class ExampleViewModel : ViewModel() {
private val compositeDisposable = CompositeDisposable()
fun doSomething() {
val disposable = Single.just(1)
.subscribe {
//update something onNext
}
compositeDisposable.add(disposable)
}
override fun onCleared() {
compositeDisposable.clear()
}
}

This will work out fine however in every ViewModel we are forced to create the CompositeDisposable and wire up the onCleared function. The natural extension onto this would be to create a base class for our ViewModel which could look something like this…

abstract class DisposingViewModel : ViewModel() {
private val compositeDisposable = CompositeDisposable()
fun addDisposable(disposable: Disposable) {
compositeDisposable.add(disposable)
}
override fun onCleared() {
compositeDisposable.clear()
}
}

Then in every ViewModel that needs this code it simply just extends from the DisposingViewModel and it just has to invoke addDisposable. If you are against the idea of inheritance being used in this way (you aren’t alone) then it’s worth noting that creating a solution for this using class delegation in Kotlin is not much more work.

Is There An Even Better Way?

There might be. Whether it be a more home grown solution or a battle tested open source project I’m sure something out there exists. At this time I wanted to write a follow-up article so I could deprecate the previous one that continues to rank well on Google and potentially mislead developers. So more on that to come, in the mean time if you have additional thoughts feel free to leave a comment.

Thanks for taking the time to read through my article. If you found something to be not quite right or have other information to add please reach out in the comments section below. If you enjoyed this article, please click on the clap icon a few times or share it on social media (or both). Lastly, I’m starting up a mailing list that is powered by ActiveCampaign, if you want to get weekly newsletters then please use the sign-up form located here.

--

--