In this post i want explain what is LiveData and how you can use it.

1) What is LiveData

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. -Google

As quoted above, LiveData is a data holder class, introduced as part of the Android Architecture Components at Google I/O ’17. I see it as a lite version of RxJava’s Observables with the advantage that it only emits data when the observer is active. With using LiveData your UI can always react to the newest values of the data you are observing.

Observe changes

Asynchronous

To observe the changes of a LiveData asynchronous you have two options:
Observe with LifeCycle Owner

observe(LifeCycleOwner,Observer)
The observe() method needs a LifeCyclerOwner and an Observer.
A LifeCycleOwner is a class which implements a LifeCycleOwner interface like Activity or Fragment. The advantage is that LiveData detects the LifeCycle and it will be automatic removed when your class is destroyed.
The onChanged() method will be triggered every time something changes the value of the observed LiveData.

Observe without LifeCycle Owner

observeForever(Observer)
You can also use observeForever() to observe LiveData without a LifeCycleOwner, but as the name indicates it will not be removed automatically. It is important to manually remove the observer with removeObserver(), otherwise it could cause memory leaks.

Synchronous

getValue()
getValue() will return the value of LiveData at the moment the method gets called. You will not be informed about any changes at the object.

2) MutableLiveData

MutableLiveData is a Subclass of LiveData. Because LiveData has no methods to change the value, you have to use a MutableLiveData. It offers two methods to set a value.

setValue()
You have to use setValue() when you are working on the mainThread.

postValue()
You have to use postValue(), when you are changing the value from a background thread.

3) Transformations of LiveData

LiveData comes with a few special classes that are useful if you need to transform your observed LiveData Objects.

3.1) Transformations

.map()

Transformations can be useful when you have data stored as LiveData, but you might have a special case where you want to make changes before to the emitting the data.
You can see an example below in Scenario 2.

.switchMap()
switchMap() does the same as map(), but it has to return a LiveData object.

3.2) MediatorLiveData

MediatorLiveData is a LiveData class which can observe multiple LiveData Objects.

addSource(LiveData, Observer)
Starts to listen the given source LiveData, onChanged observer will be called when source value was changed.

removeSource(LiveData)
Stops to listen the given LiveData.

setValue(Object)
You can set the value like a MutableLiveData object.

You can see an example in Scenario 4.

3.3) LiveDataReactiveStreams

With LiveDataReactiveStreams you can transform LiveData to RxJava and vice versa. It has two methods.

LiveDataReactiveStreams.toPublisher()
This method will observe a LiveData object and converts it to an Observable.

LiveDataReactiveStreams.fromPublisher()
You can use this method convert Flowables from RxJava into LiveData.

You can see an example in Scenario 5 and 6.

4) Add to project

Add this to your build.gradle

If you want to use LiveDataReactiveStreams to combine LiveData with RxJava have to also add this:

5) Example project

I created an example project that is using LiveData in different scenarios, you can find it on Github.

Example Project

Example Project

Scenario 1

PlantUML Syntax:
MainActivity -> JKViewModel: increment()
JKViewModel -> JKViewModel: updates value \n of LiveData
JKViewModel -> MainActivity: returns the \n new value of LiveData

In the ViewModel i created a variable “count” that holds a value and a MutableLiveData that will emit the object “count”.

The Buttons +1 and -1 tell the ViewModel to increase or decrease the value of count.

The value of count gets increased, then it will be set as the value of the MutableLiveData count1

The ViewModel has a getCount() method to get the MutableLiveData. It is returned as LiveData so the other classes than the ViewModel have no option to change the value of it and can just observe the value.

In the MainActivity i am using the method to observe count1 and set the value to a TextView.

Scenario 2

PlantUML Syntax:
JKViewModel -> JKViewModel: count1 \n is changed
JKViewModel -> JKViewModel: transforms value \n of count1
JKViewModel –> MainActivity: returns the \n new value as LiveData

Here i’m using the Transformations class to emit the value of count as a String. The map method observes the value of getCount() and converts the value to a String. Then it emits this String as LiveData.

Like in Scenario 1 i’m observing the changes of getCount1AsString() and set the value to a TextView.

Scenario 3

This does the same as Scenario 1 but it has the variable secoundCount instead of count. It’s just there to show the use of MediatorLiveData in Scenario 4.

Scenario 4

Here i’m using MediatorLiveData. I’m adding getCount() and getCount2() as a source for it. Every time one of the two sources change, the value will be set as a value of MediatorLiveData.

Scenario 5

Here i’m using LiveDataReactiveStreams.fromPublisher to show how you can convert a Flowable from RxJava to a LiveData Object.

My test Flowable will only emit the String “Hello World” one time.

Scenario 6

Here i’m using LiveDataReactiveStreams.toPublisher. It is the opposite of Scenario 5. A LiveData objects gets converted to a Observable.

Resources

LiveData
LiveDataReactiveStreams