Internals of Android Architecture Components Part II— LiveData

Josep Rodriguez
May 27, 2018 · 4 min read

This post series explores the implementation of Android Architecture Components (AAC) so we make the magic go away. In this instalment we’ll focus on . You can see the other posts here:

  1. The ViewModel
  2. LiveData

What is LiveData?

Photo by Chris Liverani on Unsplash

Let’s look at the definition from Android’s documentation:

L is 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.

In summary:

  • follows the Observer pattern, notifying subscribers of new data being available.
  • is aware, which means that it will notify subscribers only when it’s in an active lifecycle state, and it will dispose the subscription when the terminates 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:

First, the creates a and exposes it. Then, the will consume it by creating an , and calling .

Diving into , we can see how it manages the subscriptions:

The first thing we notice is that depends on a and the instance we create. When the lifecycle is not in the state, creates a instance using the and the .

After ensuring we don’t add twice the same with different s, it sets the wrapper to listen for events.

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. will assert we are on the main thread, update to hold the latest data, and notify the observers.

In we can see that it will invalidate a previous dispatch if needed, and iterate the observers using where:

  • It checks that the lifecycle is active.
  • It checks that the version dispatched is newer than the last version received.
  • Calls with the data we are setting.

We’ll revisit later how won’t post the event if the is not active, and as a note; 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 will be reused while the is destroyed and recreated, and will continue to work undisturbed by events such as screen rotations and backgrounding the app.

When we looked at how the is observed, we noticed that a is created by wrapping the real observer and the .

Disposing the subscription

When the or 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:

  • actively checks the Lifecycle state of the owner
  • will remove from the observer list when the state is reached. This allows to create the observer in without having to worry about unsubscribing or disposing of it in any other way in .

Finally, how does implement and when is it tagged as ?

The first thing we can see is that uses a as the instance of , and that is passed into the constructor. Our guess is that will be listening to state changes in it, however it seems to be doing so in a somewhat obscure way. We’ll resort to using a breakpoint in to inspect the stack trace of callers:

When the control flow is not clear enough, a breakpoint is your friend.

Browsing the stack trace, we can see that the events are sent from a instance.

The is injected in the in , and behaves as a headless :

Delaying notifications on non-active Lifecycle state

Remember how didn’t post the events when the is inactive? Let’s look at how we recover the data when the becomes active again.

The key is in where calls , implemented in , to re-submit the latest value when it becomes active again:

Summary

  • proposes an Observer pattern as a solution to simplify how to pass data to components across their lifecycle.
  • will always dispatch events to the main thread.
  • builds upon the AAC.
  • Any object implementing can be used with. Most of the time you’ll be using // which already implement it for you.
  • will not deliver values while the is inactive (e.g. paused), and will submit as soon as the becomes active again (e.g. resumed).
  • simplifies by automatically disposing observers when the event is triggered in the lifecycle.
  • On (and all subclasses) Android uses yet again a headless to split responsibilities. In this case, is used to dispatch lifecycle events to observers.
  • dispatches the events on the methods, where XYZ is a lifecycle event.

The Lair

Tigerspike's way of exploring how technology and design can benefit humans.

Josep Rodriguez

Written by

Mobile Tech Lead @ Tigerspike

The Lair

The Lair

Tigerspike's way of exploring how technology and design can benefit humans.