The rights of this image are for erikcaffrey.github.io

LiveData & ViewModel — Making your own magic

Marcos Sandoval

User Experience(UX) is probably the most critical part of any product creation. To the final user it doesn’t a matter if you use the best material to build your product or the best algorithms to create your software or if you do it as efficient as possible, if your product doesn’t offer a good experience to the user it won’t use it, that’s simple.

User experience is composed of a lot of elements, for instance: UI composition, navigation pattern, colors, fonts, data accuracy, etc. On this post we will focus on data accuracy and how Google architectural components can help us to create apps that keep automatically synchronized the UI with the data on the model.

LiveData

LiveData is an observable data holder class

As Google defined it, LiveData is a class that has only one property, it allows us to save/hold any object into that property. But LiveData is more than that, it is an observable class, which means it implements the observable design pattern, which allows us to subscribe entities that will be notified when the data contained on the LiveData class change. But there is one more feature that makes LiveData a very good option to include it on our project. LiveData class is lifecycle-aware, which means it respects and it is aware of the lifecycle state of the observer subscribed to it.

If you want to learn more about lifecycle-aware components and how to create your own, I strongly recommend reading my article about it.

The reasons to use LiveData can be summarized in the follows:

  • Data/UI synchronization: Because LiveData follows the observable pattern it will notify the UI of any changes, this ensures perfect data synchronization between the two layers without any manual data change verification.
  • No more life-cycle related crashes: Since LiveData is a lifecycle aware component it ensures to remove any lifecycleObserver when its status is destroyed, avoiding memory leaks due to unused/inexistence references. Also, LiveData will only send notification about data change only to the observers that are on an active state like onResume.
  • No more manual data update: Observable pattern allows to avoid manual work to update and synchronize the UI with our data. When a configuration change happens or when it returns from an inactive state to active state it will receive the latest data right after it came back, this happens on the OnCreate when the ViewModelProviders is called, as we will see below

ViewModel

ViewModel is a helper class which is part of the Android Architecture Components, it helps us to store, manage and prepare UI related data in a lifecycle conscious way. The main benefit of the ViewModel is that it is created the first time and if the Activity, Fragment or any other LifecycleOwner is destroyed or recreated by the system, the next time it starts it will receive the same ViewModel created before. It works like a Loader (AsyncTaskLoader and CursorLoader)

ViewModel lifecycle

As we noticed in the image above, the ViewModel is kept alive even when the Activity is destroyed or reconstructed due to a configuration change for example. When the activity is finished the ViewModel calls the onCleared() method to clean up any remaining resource and avoid memory leaks.

We must keep in mind:

  • A ViewModel class shouldn’t have any reference to LifecycleOwner, like Activity or fragment, or to the context, this makes the unit testing easier
  • ViewModel object can contain LifecycleObservers , such as LiveData objects, but a ViewModel must never observe changes to lifecycle-aware observables, this has to be done on the LifecycleOwner
  • If the ViewModel needs the Application context it should extend AndroidViewModel and receive the Application on the constructor

Ok, let’s check the code

For this article, we will continue using the example created for the article about Room I posted some months ago, you can visit and read the article on this link to get context about the sample or learn about Room. Also, all the sample codes are written using Kotlin, if you don’t know Kotlin or you want to learn more, I would invite you to visit this link and read my article about it.

The first thing we need to do is to update our gradle file. It should look like the following

App.gradle

As we mentioned above, ViewModel object can contain LifecycleObservers , such as LiveData object, so that let’s see how do they interact with each other.

MainViewModel.kt

Things to notice here:

  • Our custom ViewModel class have to extend from ViewModel.
  • The ViewModel class receives only one parameter on the constructor, which is the repository that handles our data. This class is out of the scope of the article but it can be consulted on the repository of this example.
  • The class has another property, besides the repository, which is a MutableLiveData object that contains/holds a list of Genders . This means we can subscribe to this property to be aware of its changes and react to them, as we will see below. A LiveData object can hold any type of object, in this case it is declared as Mutable since we want to be able to modify its content.
  • Finally, we have a ViewModelFactory which implements ViewModelProvider.Factory interface, this is necessary if you need to pass any parameter to your ViewModel, if not you omit that fragment of code

Now let's see how to use our ViewModel

MainActivity.kt

What are we doing?

  • We are getting an instance of our database.
  • Then, we are getting an instance of our ViewModel using the ViewModelProvider, this provider will check if there is an instance of the same class already created if so it will return it, with all the data up-to-date. If a ViewModel has not been created yet, it will be created for us. This ensures each time a configuration change or any similar event happens, we won’t lose the current state of our data nor we will create a new instance of the ViewModel each time.
  • Finally, we are subscribing to observe and react properly to any change that occurs to the list of gender store on the ViewModel.

If you don’t need to pass any parameter to the ViewModel class you can omit the implementation of the ViewModelProvider.Factory interface, as we mentioned before, and the call to get an instance of the ViewModel can be simplified like the following example

And that’s it :). We have learned how to start building a Reactive MVVM architecture by using Android Architectural components, we will have a more detailed article about reactive apps very soon.

Also! The whole code of the project can be found from here. Thanks for reading!

MindOrks

Our community publishes stories worth reading on software development and design. Android | Machine Learning | #MakeEveryoneCode

Marcos Sandoval

Written by

Programmer, traveler and dreamer https://cr.linkedin.com/in/marcos-sandoval-calvo

MindOrks

MindOrks

Our community publishes stories worth reading on software development and design. Android | Machine Learning | #MakeEveryoneCode