abstract class LiveData<T>

Known direct subclasses
MutableLiveData

LiveData which publicly exposes setValue and postValue method.

SliceLiveData.CachedSliceLiveData

Implementation of LiveDatathat provides controls over how cached vs live slices work.

Known indirect subclasses
MediatorLiveData

LiveData subclass which may observe other LiveData objects and react on OnChanged events from them.


LiveData is a data holder class that can be observed within a given lifecycle. This means that an Observer can be added in a pair with a LifecycleOwner, and this observer will be notified about modifications of the wrapped data only if the paired LifecycleOwner is in active state. LifecycleOwner is considered as active, if its state is STARTED or RESUMED. An observer added via observeForever is considered as always active and thus will be always notified about modifications. For those observers, you should manually call removeObserver.

An observer added with a Lifecycle will be automatically removed if the corresponding Lifecycle moves to DESTROYED state. This is especially useful for activities and fragments where they can safely observe LiveData and not worry about leaks: they will be instantly unsubscribed when they are destroyed.

In addition, LiveData has onActive and onInactive methods to get notified when number of active Observers change between 0 and 1. This allows LiveData to release any heavy resources when it does not have any Observers that are actively observing.

This class is designed to hold individual data fields of ViewModel, but can also be used for sharing data between different modules in your application in a decoupled fashion.

Parameters
<T>

The type of data held by this instance

See also
ViewModel

Summary

Public constructors

Creates a LiveData with no value assigned to it.

LiveData(value: T!)

Creates a LiveData initialized with the given value.

Public functions

T?

Returns the current value.

Boolean

Returns true if this LiveData has active observers.

Boolean

Returns true if this LiveData has observers.

Boolean

Returns whether an explicit value has been set on this LiveData.

Unit
@MainThread
observe(owner: LifecycleOwner, observer: Observer<Any!>)

Adds the given observer to the observers list within the lifespan of the given owner.

Unit

Adds the given observer to the observers list.

Unit

Removes the given observer from the observers list.

Unit

Removes all observers that are tied to the given LifecycleOwner.

Protected functions

Unit

Called when the number of active observers change from 0 to 1.

Unit

Called when the number of active observers change from 1 to 0.

Unit
postValue(value: T!)

Posts a task to a main thread to set the given value.

Unit
@MainThread
setValue(value: T!)

Sets the value.

Extension functions

Flow<T>
<T : Any?> LiveData<T>.asFlow()

Creates a Flow containing values dispatched by originating LiveData: at the start a flow collector receives the latest value held by LiveData and then observes LiveData updates.

State<T?>

Starts observing this LiveData and represents its values via State.

State<R>
@Composable
<R : Any?, T : R> LiveData<T>.observeAsState(initial: R)

Starts observing this LiveData and represents its values via State.

inline Observer<T>
@MainThread
<T : Any?> LiveData<T>.observe(
    owner: LifecycleOwner,
    crossinline onChanged: (T) -> Unit
)

This function is deprecated. This extension method is not required when using Kotlin 1.4.

Publisher<T>
<T : Any?> LiveData<T>.toPublisher(lifecycle: LifecycleOwner)

Adapts the given LiveData stream to a ReactiveStreams Publisher.

LiveData<PagingData<T>>
<T : Any> LiveData<PagingData<T>>.cachedIn(lifecycle: Lifecycle)

Operator which caches a LiveData of PagingData within the scope of a Lifecycle.

LiveData<PagingData<T>>

Operator which caches a LiveData of PagingData within a CoroutineScope.

LiveData<PagingData<T>>
<T : Any> LiveData<PagingData<T>>.cachedIn(viewModel: ViewModel)

Operator which caches a LiveData of PagingData within the scope of a ViewModel.

LiveData<X>

Creates a new LiveData object does not emit a value until the source this LiveData value has been changed.

LiveData<Y>
@MainThread
<X : Any?, Y : Any?> LiveData<X>.map(transform: (X) -> Y)

Returns a LiveData mapped from this LiveData by applying transform to each value set on this LiveData.

LiveData<Y>
@MainThread
<X : Any?, Y : Any?> LiveData<X>.switchMap(transform: (X) -> LiveData<Y>)

Returns a LiveData mapped from the input this LiveData by applying transform to each value set on this.

Public constructors

LiveData

Added in 2.0.0
LiveData()

Creates a LiveData with no value assigned to it.

LiveData

Added in 2.1.0
LiveData(value: T!)

Creates a LiveData initialized with the given value.

Parameters
value: T!

initial value

Public functions

getValue

Added in 2.0.0
fun getValue(): T?

Returns the current value.

Note that calling this method on a background thread does not guarantee that the latest value set will be received.

Returns
T?

the current value or null if isInitialized is false

hasActiveObservers

Added in 2.0.0
fun hasActiveObservers(): Boolean

Returns true if this LiveData has active observers.

Returns
Boolean

true if this LiveData has active observers

hasObservers

Added in 2.0.0
fun hasObservers(): Boolean

Returns true if this LiveData has observers.

Returns
Boolean

true if this LiveData has observers

isInitialized

Added in 2.6.0
fun isInitialized(): Boolean

Returns whether an explicit value has been set on this LiveData. If this returns true, then the current value can be retrieved from getValue.

Note that calling this method on a background thread may still result in this method returning false even if a call to postValue is being processed.

Returns
Boolean

whether an explicit value has been set on this LiveData

observe

@MainThread
fun observe(owner: LifecycleOwner, observer: Observer<Any!>): Unit

Adds the given observer to the observers list within the lifespan of the given owner. The events are dispatched on the main thread. If LiveData already has data set, it will be delivered to the observer.

The observer will only receive events if the owner is in STARTED or RESUMED state (active).

If the owner moves to the DESTROYED state, the observer will automatically be removed.

When data changes while the owner is not active, it will not receive any updates. If it becomes active again, it will receive the last available data automatically.

LiveData keeps a strong reference to the observer and the owner as long as the given LifecycleOwner is not destroyed. When it is destroyed, LiveData removes references to the observer &the owner.

If the given owner is already in DESTROYED state, LiveData ignores the call.

If the given owner, observer tuple is already in the list, the call is ignored. If the observer is already in the list with another owner, LiveData throws an IllegalArgumentException.

Parameters
owner: LifecycleOwner

The LifecycleOwner which controls the observer

observer: Observer<Any!>

The observer that will receive the events

observeForever

@MainThread
fun observeForever(observer: Observer<Any!>): Unit

Adds the given observer to the observers list. This call is similar to observe with a LifecycleOwner, which is always active. This means that the given observer will receive all events and will never be automatically removed. You should manually call removeObserver to stop observing this LiveData. While LiveData has one of such observers, it will be considered as active.

If the observer was already added with an owner to this LiveData, LiveData throws an IllegalArgumentException.

Parameters
observer: Observer<Any!>

The observer that will receive the events

removeObserver

@MainThread
fun removeObserver(observer: Observer<Any!>): Unit

Removes the given observer from the observers list.

Parameters
observer: Observer<Any!>

The Observer to receive events.

removeObservers

Added in 2.0.0
@MainThread
fun removeObservers(owner: LifecycleOwner): Unit

Removes all observers that are tied to the given LifecycleOwner.

Parameters
owner: LifecycleOwner

The LifecycleOwner scope for the observers to be removed.

Protected functions

onActive

Added in 2.0.0
protected fun onActive(): Unit

Called when the number of active observers change from 0 to 1.

This callback can be used to know that this LiveData is being used thus should be kept up to date.

onInactive

Added in 2.0.0
protected fun onInactive(): Unit

Called when the number of active observers change from 1 to 0.

This does not mean that there are no observers left, there may still be observers but their lifecycle states aren't STARTED or RESUMED (like an Activity in the back stack).

You can check if there are observers via hasObservers.

postValue

Added in 2.0.0
protected fun postValue(value: T!): Unit

Posts a task to a main thread to set the given value. So if you have a following code executed in the main thread:

liveData.postValue("a");
liveData.setValue("b");
The value "b" would be set at first and later the main thread would override it with the value "a".

If you called this method multiple times before a main thread executed a posted task, only the last value would be dispatched.

Parameters
value: T!

The new value

setValue

Added in 2.0.0
@MainThread
protected fun setValue(value: T!): Unit

Sets the value. If there are active observers, the value will be dispatched to them.

This method must be called from the main thread. If you need set a value from a background thread, you can use postValue

Parameters
value: T!

The new value

Extension functions

fun <T : Any?> LiveData<T>.asFlow(): Flow<T>

Creates a Flow containing values dispatched by originating LiveData: at the start a flow collector receives the latest value held by LiveData and then observes LiveData updates.

When a collection of the returned flow starts the originating LiveData becomes active. Similarly, when a collection completes LiveData becomes inactive.

BackPressure: the returned flow is conflated. There is no mechanism to suspend an emission by LiveData due to a slow collector, so collector always gets the most recent value emitted.

@Composable
fun <T : Any?> LiveData<T>.observeAsState(): State<T?>

Starts observing this LiveData and represents its values via State. Every time there would be new value posted into the LiveData the returned State will be updated causing recomposition of every State.value usage.

The inner observer will automatically be removed when this composable disposes or the current LifecycleOwner moves to the Lifecycle.State.DESTROYED state.

import androidx.compose.material.Text
import androidx.compose.runtime.livedata.observeAsState

val value: String? by liveData.observeAsState()
Text("Value is $value")
@Composable
fun <R : Any?, T : R> LiveData<T>.observeAsState(initial: R): State<R>

Starts observing this LiveData and represents its values via State. Every time there would be new value posted into the LiveData the returned State will be updated causing recomposition of every State.value usage.

The initial value will be used only if this LiveData is not already initialized. Note that if T is a non-null type, it is your responsibility to ensure that any value you set on this LiveData is also non-null.

The inner observer will automatically be removed when this composable disposes or the current LifecycleOwner moves to the Lifecycle.State.DESTROYED state.

import androidx.compose.material.Text
import androidx.compose.runtime.livedata.observeAsState

val value: String by liveData.observeAsState("initial")
Text("Value is $value")
@MainThread
inline fun <T : Any?> LiveData<T>.observe(
    owner: LifecycleOwner,
    crossinline onChanged: (T) -> Unit
): Observer<T>

Adds the given onChanged lambda as an observer within the lifespan of the given owner and returns a reference to observer. The events are dispatched on the main thread. If LiveData already has data set, it will be delivered to the onChanged.

The observer will only receive events if the owner is in Lifecycle.State.STARTED or Lifecycle.State.RESUMED state (active).

If the owner moves to the Lifecycle.State.DESTROYED state, the observer will automatically be removed.

When data changes while the owner is not active, it will not receive any updates. If it becomes active again, it will receive the last available data automatically.

LiveData keeps a strong reference to the observer and the owner as long as the given LifecycleOwner is not destroyed. When it is destroyed, LiveData removes references to the observer and the owner.

If the given owner is already in Lifecycle.State.DESTROYED state, LiveData ignores the call.

fun <T : Any?> LiveData<T>.toPublisher(lifecycle: LifecycleOwner): Publisher<T>

Adapts the given LiveData stream to a ReactiveStreams Publisher.

By using a good publisher implementation such as RxJava 2.x Flowables, most consumers will be able to let the library deal with backpressure using operators and not need to worry about ever manually calling Subscription.request.

On subscription to the publisher, the observer will attach to the given LiveData. Once Subscription.request is called on the subscription object, an observer will be connected to the data stream. Calling request(Long.MAX_VALUE) is equivalent to creating an unbounded stream with no backpressure. If request with a finite count reaches 0, the observer will buffer the latest item and emit it to the subscriber when data is again requested. Any other items emitted during the time there was no backpressure requested will be dropped.

fun <T : Any> LiveData<PagingData<T>>.cachedIn(lifecycle: Lifecycle): LiveData<PagingData<T>>

Operator which caches a LiveData of PagingData within the scope of a Lifecycle.

cachedIn multicasts pages loaded and transformed by a PagingData, allowing multiple observers on the same instance of PagingData to receive the same events, avoiding redundant work, but comes at the cost of buffering those pages in memory.

Calling cachedIn is required to allow calling androidx.paging.AsyncPagingDataAdapter on the same instance of PagingData emitted by Pager or any of its transformed derivatives, as reloading data from scratch on the same generation of PagingData is an unsupported operation.

Parameters
lifecycle: Lifecycle

The Lifecycle where the page cache will be kept alive.

fun <T : Any> LiveData<PagingData<T>>.cachedIn(scope: CoroutineScope): LiveData<PagingData<T>>

Operator which caches a LiveData of PagingData within a CoroutineScope.

cachedIn multicasts pages loaded and transformed by a PagingData, allowing multiple observers on the same instance of PagingData to receive the same events, avoiding redundant work, but comes at the cost of buffering those pages in memory.

Calling cachedIn is required to allow calling androidx.paging.AsyncPagingDataAdapter on the same instance of PagingData emitted by Pager or any of its transformed derivatives, as reloading data from scratch on the same generation of PagingData is an unsupported operation.

Parameters
scope: CoroutineScope

The CoroutineScope where the page cache will be kept alive. Typically this would be a managed scope such as ViewModel.viewModelScope, which automatically cancels after the PagingData stream is no longer needed. Otherwise, the provided CoroutineScope must be manually cancelled to avoid memory leaks.

fun <T : Any> LiveData<PagingData<T>>.cachedIn(viewModel: ViewModel): LiveData<PagingData<T>>

Operator which caches a LiveData of PagingData within the scope of a ViewModel.

cachedIn multicasts pages loaded and transformed by a PagingData, allowing multiple observers on the same instance of PagingData to receive the same events, avoiding redundant work, but comes at the cost of buffering those pages in memory.

Calling cachedIn is required to allow calling androidx.paging.AsyncPagingDataAdapter on the same instance of PagingData emitted by Pager or any of its transformed derivatives, as reloading data from scratch on the same generation of PagingData is an unsupported operation.

Parameters
viewModel: ViewModel

The ViewModel whose viewModelScope will dictate how long the page cache will be kept alive.

distinctUntilChanged

@MainThread
fun <X : Any?> LiveData<X>.distinctUntilChanged(): LiveData<X>

Creates a new LiveData object does not emit a value until the source this LiveData value has been changed. The value is considered changed if equals() yields false.

Returns
LiveData<X>

a new LiveData of type X

@MainThread
fun <X : Any?, Y : Any?> LiveData<X>.map(transform: (X) -> Y): LiveData<Y>

Returns a LiveData mapped from this LiveData by applying transform to each value set on this LiveData.

This method is analogous to io.reactivex.Observable.map.

transform will be executed on the main thread.

Here is an example mapping a simple User struct in a LiveData to a LiveData containing their full name as a String.

val userLD : LiveData<User> = ...;
val userFullNameLD: LiveData<String> = userLD.map { user -> user.firstName + user.lastName }
Parameters
transform: (X) -> Y

a function to apply to each value set on source in order to set it on the output LiveData

Returns
LiveData<Y>

a LiveData mapped from source to type <Y> by applying mapFunction to each value set.

@MainThread
fun <X : Any?, Y : Any?> LiveData<X>.switchMap(transform: (X) -> LiveData<Y>): LiveData<Y>

Returns a LiveData mapped from the input this LiveData by applying transform to each value set on this.

The returned `LiveData` delegates to the most recent `LiveData` created by [transform] with the most recent value set to `this`, without changing the reference. In this way [transform] can change the 'backing' `LiveData` transparently to any observer registered to the `LiveData` returned by `switchMap()`.

Note that when the backing LiveData is switched, no further values from the older LiveData will be set to the output LiveData. In this way, the method is analogous to io.reactivex.Observable.switchMap.

transform will be executed on the main thread.

Here is an example class that holds a typed-in name of a user String (such as from an EditText) in a MutableLiveData and returns a LiveData containing a List of User objects for users that have that name. It populates that LiveData by requerying a repository-pattern object each time the typed name changes.

This `ViewModel` would permit the observing UI to update "live" as the user ID text changes.

class UserViewModel: AndroidViewModel {
val nameQueryLiveData : MutableLiveData<String> = ...

fun usersWithNameLiveData(): LiveData<List<String>> = nameQueryLiveData.switchMap {
name -> myDataSource.usersWithNameLiveData(name)
}

fun setNameQuery(val name: String) {
this.nameQueryLiveData.value = name;
}
}
Parameters
transform: (X) -> LiveData<Y>

a function to apply to each value set on source to create a new delegate LiveData for the returned one

Returns
LiveData<Y>

a LiveData mapped from source to type <Y> by delegating to the LiveData returned by applying switchMapFunction to each value set