Thinking in LiveData

Jeff Li
4 min readNov 12, 2021

Nowadays, the MVVM architecture has been accepted widely as a standard on the development of mobile platforms for years(meanwhile, some people are trying to explore the possibility of MVI and we may discuss it in my next post). On the Android side, the LiveData is a really important class in using View Model. So here I plan to show some thoughts about LiveDatabased on my experience.

What is LiveData?

LiveData is a data holder class that can be observed within a given lifecycle.

— Google Official Doc

Basically, LiveDatais the observable with the awareness of lifecycles of app components, like activities, fragments, etc. The data in this holder is live cos only active observers can be notified when there is a data update. From the perspective of the lifecycle, only STARTEDand RESUMEDstates can be considered as being active. Furthermore, observers registered in the LiveDatawill be removed automatically once they run into the DESTROYEDstate.

How to use LiveData?

Case 1:

According to the design of LiveData, which is observed in the main thread and only notifies its observers whose lifecycles are at STARTEDor RESUMED, the common use case is to hold the data fields of the View Model to update the UI elements.

Since LiveDatais aware of its observers’ lifecycle, it won’t try to update the UI when the app is running in the background. For those inactive observers, only the latest data will be received once they become active again.

Note: if there is no update since the last time it is active, it won’t be notified. The internal implementation is kind of trivial: there is a specific version that is associated with the data for each observer and the version will be checked before the notification is dispatched. For this reason, the observer that comes in anew will receive the latest data, which makes the LiveData be able to handle the recovery properly in the configuration change.

In addition, no worries about the memory leaks cos observers will be cleaned up after they are destroyed.

Case 2:

Another use case for LiveDatais relatively rare which is based on an additional trait of LiveData: it monitors the number of active observers. The onActive() and onInactive()get called when the number of active Observer changes between 0 and 1.

Note: it does not have to get all observers removed to trigger onInactive(). If all observers become inactive, the onInactive() can get notified.

Thanks to this trait, it makes LiveDataa good candidate for sharing data between different LifecycleOwners, such as activities and fragments.

For example, you have a global data service in your app that keeps pulling the latest data from the server-side, and multiple pages(activities and fragments) need to observe the data change to display the UI. In the old fashion, you probably want to register an observer when the page is in the foreground and unregister the observer after the page is in the background cos it does not make sense to listen to the data change when the app is not visible to users. You have to do this manually for all pages that need to show the data from the global data service. It creates boiler-plate code and leads to memory leak easily if the unregistration is missed.

However, with the help of LiveData, you can do something like:

In this way, you can just create a LiveDatain your pages like:

No manual handling its lifecycle cos the listener will be removed and notification will be stopped when the app is background;

No concern about memory leak cos the listener will be removed after all observers to the LiveDataare destroyed.

The Last Thinking

The LiveDatais under the lifecycle package of Android Jetpack. It is highly tailored for dealing with lifecycle-related stuff. So it might not be a good idea to explore its usage in other cases that have no business with lifecycle components. Like, you should not replace your regular implementation of the observer pattern with LiveDatamerely because it is observable. The reason is that there is some overhead and specific design only for LifecycleOwner . Besides, its observers can only be notified in the main thread. So it is also a bad idea to expose LiveData as an interface from your data layer cos the data layer should not care anything about Lifecycle, and many operations on the data layer should be streamable and would be done in the worker thread for performance issues.

To be honest, I don’t really like the current design of LiveData. The observeForever is not a harmonious factor and it makes LiveData escape the constraints of the lifecycle. I would prefer to make LiveData a higher-level interface and provide two different implementations based on needs if they share some common behaviors.

--

--