21 April 2022

Migrating from interface callbacks to LiveData observables in MVVM.

LiveData is data holder which observes changes of a particular view inside an activity/fragment and update it with the latest data.

Unlike a regular observable, LiveData is lifecycle-aware, meaning it respects the lifecycle of other app components, such as activities, fragments, or services. This awareness ensures LiveData only updates app component observers that are in an active lifecycle state.

Why do you need LiveData?

Imagine you have an app which contains an activity with couple of TextViews with some values, then on orientation change, you need to set values to the TextView again because the activity will be destroyed on orientation change.
By using LiveData you don’t have to worry about the orientation change because the observables do everything for you.
Here are some advantages of using LiveData in your project:

Before LiveData

I’ve been using ViewModel with interfaces as a listener and for passing data from my ViewModel to the corresponding activity. I was defining the interface in ViewModel and implementing it in activity/fragment. So whenever some event happens we simply call the method on the interface. This is simple and straightforward approach but this is an anti-pattern because in MVVM we should not have any reference to the view.

Let’s see how our the interface looks like:

mgl-interface This interface we have declared has 3 methods, they are very much self explanatory.

Let’s have a look at the ViewModel:

mgl-viewmodel In UsersViewModel we are:

Let’s have a look at the Activity:

mgl-activity In UsersActivity class we are implementing the interface, and setting the progress bar in onLoading(), and onSuccess() is used to set data to recyclerview adapter.
The onError() will show a toast with a particular error.

This violates the MVVM pattern and leads to the problem because the UsersViewModel has the reference to the UsersActivity.

Now, let’s add LiveData to the UsersViewModel and see what happens.

mgl-viewmodel2

Here, we’ll remove all the interface related stuff and add MutableLiveData which is a type of List<Users> and is immutable. Also, we will expose one LiveData with the same type which contains the all the data form MutableLiveData which is used to observe in our activity. Then we use the setValue(T) to set the value to our MutableLiveData.

And we now modify the Activity like this:

mgl-viewmodel2 Here, we’ll remove the interface implementaion and create a function getUsers() which contains:

Conclusion - LiveData is lifecycle-aware, which handles all the config changes automatically and prevents memory leak. While using MVVM pattern make sure that your activity/fragment is just used for setting the data which is recieved from the ViewModel. Also, your viewModel is dumb and don’t know anything about your views. So, ViewModel should not have any reference to the views.

back

tags: Android - LiveData - ViewModel - MVVM

Made with 💻 in India