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 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
- 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
ViewModelProvidersis called, as we will see below
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)
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
ViewModel calls the
onCleared() method to clean up any remaining resource and avoid memory leaks.
We must keep in mind:
ViewModelclass shouldn’t have any reference to
LifecycleOwner, like Activity or fragment, or to the
context, this makes the unit testing easier
ViewModelobject can contain
LifecycleObservers, such as
LiveDataobjects, but a
ViewModelmust never observe changes to lifecycle-aware observables, this has to be done on the
- If the
Applicationcontext it should extend
AndroidViewModeland receive the
Applicationon 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
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.
Things to notice here:
- Our custom ViewModel class have to extend from
ViewModelclass 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
MutableLiveDataobject 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
LiveDataobject 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.Factoryinterface, 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
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
ViewModelhas 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!