The Glue image source is https://www.shutterstock.com/image-vector/cartoon-metal-tube-super-glue-vector-557561680

RxJava instead of LiveData in MVVM

Hadi Lashkari Ghouchani
3 min readJan 8, 2020

--

It’s been a while that I use BehaviorProcessors of RxJava as io.reactivex.rxjava2 instead of LiveData in android.arch.lifecycle. For instance, you can find a class named RxLifecycleHandler in CleanArchitecture, and its usage in the BaseFragment and AlbumFragment is like the following.

BaseFragment.kt
AlbumFragment.kt

The observe extension function just passes handling of subscriptions to the RxLifecycleHandler instance. Then RxLifecycleHandler subscribes when the fragment is between onStart and onStop callbacks, otherwise it disposes. Despite I’m doing it for a while successfully, there are little people that are aware of it, so I decided to publish this article. Although, before this I thought it’s a simple idea and not worth writing, but now I think this should be the exact reason to publish it!

LiveData was deprecated

So, what is the advantage of using RxJava streams instead of LiveData?

— First of all, LiveData has just one strategy on backpressure, which is dropping, so the values are missing out if you post them fast into LiveData.

— Second, LiveData has only one strategy to hold the values, but we have PublishProcessor, BehaviorProcessor, ReplayProcessor, and etc. Or if you’re working in the main thread all the time, so have no plan to support backpressure, you can use PublishSubject, BehaviorSubject, ReplaySubject, and etc.

— Third, while you test LiveData you miss some RxJava testing sugars, such as TestObserver, TestScheduler etc.

So at least there is three disadvantages of using LiveData. But if it’s so, why we use it? Because it understands the lifecycle of Activities and Fragments in the Android framework. As you can see in the code in CleanArchitucture project, that I mentioned before, supporting such behavior is not so hard, so I made a library to handle this lifecycle. You can use it as simple as adding the dependency to your project as following. Remember that we assume here we need the emitted values just after onStart callback and before onStop.

implementation "com.github.hadilq:rxlifecyclehandler:0.1.0"

Also you can find the source code in the below link.

The same goal can be achieved by Flow implementation of Kotlin Coroutines, so I also implemented the following library for this purpose, but let’s talk about it later.

implementation "com.github.hadilq:coroutinelifecyclehandler:0.1.0"

Where you can find its source code in the below link.

RxJava

To make your life easier, as an example of ViewModel in MVVM architectural pattern, let me copy some parts of the code in CleanArchitectureFP project which is using processors instead of LiveData.

AlbumsViewModel.kt

In the above example you can see openAlbumDetailsLiveEvent, which as its name is showing, is a LiveEvent that means the ViewModel would not hold the emitted values, because of PublishProcessor implementation, but in case of networkErrorLiveData you can see after emitting a value the data would be held in the BehaviorProcessor just the same as what LiveData would do, which means, in case of configuration change the value would be passed to the new Activity or fragment. Imagine you could find a use-case for ReplayProcessor and others.

Notice

If you want to commit a fragment after receiving an event over the above method, you may need to use commitAllowingStateLoss method as the Google document mentioned, the onSaveInstanceState method may called before onStop callback in pre-Build.VERSION_CODES.P Androids. Also I have a plan to provide more solution to this.

Hope you use it and have some feedback for me. Also if you have any other ideas, please don’t forget to share with me. You can find me on Tweeter and LinkedIn

Update

You can find the improve of solution for above problem in my next article https://medium.com/@hadilq.dev/save-state-by-using-rxjava-or-kotlin-flow-526f6d282b84. Enjoy!

--

--