Understanding LiveData made simple

Elye
Elye
Oct 21, 2018 · 8 min read

Architecture components are now a big thing for Android developers. LiveData is one of the major components that we want to look in detail here.

In case you are are not familiar with Architecture Component, below might help.

In my blog above, it covers ViewModels and LiveData. But the LiveData is illustrated like just a normal data passing mechanism from ViewModels to the View. I have not done LiveData justice, and now it’s payback time for it.

So what’s so special about LiveData?

What is Live Data?

Formally it is defined as below

LiveData 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

Well, it’s a mouth full of explanation.

To make it simple let me share with you some history to understand the context better, as that helps appreciating it.

When Android first introduced, most developers started coding in a single activity project.

However, it is not ideal that everything lumps into the single God Activity class. Android Activity is hard to be unit tested too.

Due to this, everyone came up with various architecture models like MVP, MVC, MVVM… etc, where the logic side is done by another part e.g. Presenter, ViewModel, Controller, etc.

This is better as it separates logic from the view. However, it also has it’s problem. The Presenter, ViewModel, Controller, etc, are not aware of the Activity Lifecycle. It has to be told of the Activity’s lifecycle.

Google now started to think, instead of letting everyone like wild-wild west defining what to do, it came up with Architecture Components.

The components e.g. ViewModels have a special capability. They are could be made aware of the Activity LiveCycle without need the Activity telling them (at least explicitly).

Other than ViewModel, the mean that is used to communicate information back from ViewModel to Activity, the data in other words, also have the ability to be aware of the Activity’s lifecycle.

That’s the reason is call LiveData, data that is aware of the LiveCycle of the interested observer (e.g. Activity).

To illustrate better, let’s put LiveData in the center as the below diagram

From the diagram, you could see that the LiveData could be modified by the ViewModels (or whatever you like to use to modify the liveData)…

Upon updating, it would then notify all its observers (activities, fragment, service, etc). Nonetheless, unlike any other approach (e.g. Rxjava), it doesn’t blindly notify them all but instead check their live state first.

If the observer is active, then it could be notified of the change of data in the LiveData. However, if the Observer is Paused or Destroyed, it would then not be notified.

This is so cool, as we no longer need to worry about unsubscribing it onPause or onDestroy.

Besides, once the Observer is resumed, it would be immediately notified of the latest data from the LiveData.

Type of LiveData

LiveData is actually just an Abstract Class. So it can’t be used as itself. Fortunately Google has implemented some simple concrete class we could make use of.

This is the most simplest LiveData, where it would just get updated and notify it’s observer.

Defining it is as simple as below (2 lines)

To observe the LiveData is also simple. I have a fragment that observe the LiveDataA as below

The result as below, once the data is set on LiveDataA i.e. 7567 and 6269, it is detected by the Fragment

From the code, you could see

but there’s no code to unsubscribe it when the Fragment is pausing or terminating.

Even without unsubscribing it, it won’t cause any problem.

Check out the below, even when the Fragment died, the LiveData value generate i.e. 1428 is not causing crashes due to setting on an inactive Fragment.

You would also notice when the Fragment came alive again, it will fetch the latest data i.e. 1428 from the LiveData.

Imagine if you are loading data from a repository. Before you pass to the view, you would like to have it modified first.

We could still use LiveData, to pass the data across various entities as below.

We could transform the data from one LiveData and pass on to the other one using Transformations.map() function.

The behavior as shown below, where the data i.e. 5116 is transformed to a new form i.e. A:5116, before passing over to the Fragment.

Using Transformations.map is helpful to ensure that the LiveData doesn’t pass information over when the destination e.g. ViewModel and View is dead.

This is so cool, as we don’t need to worry about unsubscribing it as well.

Let’s look at underlying how Trasnformation.map is done…

Oh, it is using another type of LiveData named MediatorLiveData. Let’s dive into it…

If you observe the above code, the main interesting part of MediatorLiveData is the ability to add a source to it, and the code that changes the content of the data.

This means we could have multiple LiveData feed to one destination through the MediatorLiveData as below.

We could use MediatorLiveData directly as below

With this, you could see below, the Fragment is able to receive from both LiveDataA and LiveDataB as it change.

There’s one caveat though. If the Fragment is not alive, and the data changes both on LiveDataA and LiveDataB, when the Fragment came alive, the MediatorLiveData will take the LiveData that is last added as the source, i.e. LiveDataB.

Shown above, you could see that the Fragment upon restored, will always take from the LiveDataB, regardless if LiveDataB has change latter compare to LiveDataA or not. This is because, in the code, you could see that LiveDataB is the last added source to the MediatorLiveData.

Having the ability to listen from 2 sources of LiveData is nice. But what if we want to control to only listen to one, and not the other, and switch between them as needed, should we write our logic do to so?

We can, but we don’t need to. Google has provided us another nice function, Transformations.switchMap().

The function is simply adding source and removing previous source accordingly. So there’s only one source always feed to the MediatorLiveData.

The Switch is also a liveData. So the entire operation looks as below.

To use it, would be simply as below

With this, we could easily control which data would feed to our view as below. The data updated to the Fragment is when the connected data source change, or when the switch changes.

This is very handy to control application that has data feed from different sources controlled by certain settings (e.g. user login session).

References

The above GIFs are all created using an example app I created. You could get the source code from below

Compile and play around it, to get a good solid idea of how LiveData works.

In case you don’t like the data to be made available to from your LiveData upon subscribing to it, you could refer to the below blog

Thanks for reading. You can check out my other topics here.

You can follow me on Medium, Twitter, Facebook, and Reddit for little tips and learning on mobile development, medium writing, etc related topics. ~Elye~

Mobile App Development Publication

Sharing Mobile App Development and Learning

Elye

Written by

Elye

Passionate about learning, and sharing mobile development and others https://twitter.com/elye_project https://www.facebook.com/elye.proj

Mobile App Development Publication

Sharing iOS, Android and relevant Mobile App Development Technology and Learning

Elye

Written by

Elye

Passionate about learning, and sharing mobile development and others https://twitter.com/elye_project https://www.facebook.com/elye.proj

Mobile App Development Publication

Sharing iOS, Android and relevant Mobile App Development Technology and Learning

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store