Internals of Android Architecture Components Part II— LiveData
What is LiveData?
Let’s look at the definition from Android’s documentation:
iveDatais an observable data holder class. 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.
LiveDatafollows the Observer pattern, notifying subscribers of new data being available.
Lifecycleaware, which means that it will notify subscribers only when it’s in an active lifecycle state, and it will dispose the subscription when the
Lifecycleterminates and is destroyed.
How does LiveData implement the Observer pattern?
Now that we have a brief introduction to the concept, let’s look at how it implements the Observer pattern.
The following snippet is how LiveData is expected to be consumed, as specified by Android’s documentation:
ViewModel creates a
MutableLiveData and exposes it. Then, the
Activity will consume it by creating an
Observer, and calling
observe, we can see how it manages the subscriptions:
The first thing we notice is that
observe depends on a
LifecycleOwner and the
Observer instance we create. When the lifecycle is not in the
observe creates a
LifecycleBoundObserver instance using the
LifecycleOwner and the
After ensuring we don’t add twice the same
Observer with different
LifecycleOwners, it sets the wrapper to listen for
Now that we know how subscription works, let’s look at how the notification of observers is executed:
Setting the value is rather straight forward.
LiveData will assert we are on the main thread, update
mData to hold the latest data, and notify the observers.
dispatchingValue we can see that it will invalidate a previous dispatch if needed, and iterate the observers using
- It checks that the lifecycle is active.
- It checks that the version dispatched is newer than the last version received.
onChangedwith the data we are setting.
We’ll revisit later how
considerNotify won’t post the event if the
Lifecycle is not active, and as a note;
postValue is able to dispatch new data from any thread in a safe manner, but this is outside of the scope of this article.
How doesLiveData become Lifecycle aware?
As we disovered from the first post of this series, the
ViewModel will be reused while the
Activity is destroyed and recreated, and
LiveData will continue to work undisturbed by events such as screen rotations and backgrounding the app.
When we looked at how the
LiveData is observed, we noticed that a
LifecycleBoundObserver is created by wrapping the real observer and the
Disposing the subscription
Fragment is destroyed, the subscription will have to be automatically disposed. Let’s look into how it’s achieved by looking at the
In the implementation we can see:
shouldBeActiveactively checks the Lifecycle state of the owner
thisfrom the observer list when the
DESTROYEDstate is reached. This allows to create the observer in
onCreatewithout having to worry about unsubscribing or disposing of it in any other way in
Finally, how does
LifecycleOwner and when is it tagged as
The first thing we can see is that
SupportActivity uses a
LifecycleRegistry as the instance of
Lifecycle, and that
this is passed into the constructor. Our guess is that
LifecycleRegistry will be listening to
Activity state changes in it, however it seems to be doing so in a somewhat obscure way. We’ll resort to using a breakpoint in
onStateChanged to inspect the stack trace of callers:
Browsing the stack trace, we can see that the events are sent from a
ReportFragment is injected in the
onCreate, and behaves as a headless
Delaying notifications on non-active Lifecycle state
considerNotify didn’t post the events when the
Lifecycle is inactive? Let’s look at how we recover the data when the
Lifecycle becomes active again.
The key is in
activeStateChanged, implemented in
ObservableWrapper, to re-submit the latest value when it becomes active again:
LiveDataproposes an Observer pattern as a solution to simplify how to pass data to components across their lifecycle.
LiveDatawill always dispatch events to the main thread.
LiveDatabuilds upon the
- Any object implementing
LifecycleOwnercan be used with
LiveData. Most of the time you’ll be using
Servicewhich already implement it for you.
LiveDatawill not deliver values while the
Lifecycleis inactive (e.g. paused), and will submit as soon as the
Lifecyclebecomes active again (e.g. resumed).
LifecycleOwnerby automatically disposing observers when the
DESTROYEDevent is triggered in the lifecycle.
SupportActivity(and all subclasses) Android uses yet again a headless
Fragmentto split responsibilities. In this case,
ReportFragmentis used to dispatch lifecycle events to observers.
android.support.v4.app.Fragmentdispatches the events on the
performXYZ()methods, where XYZ is a lifecycle event.