androidx.lifecycle

Interfaces

DefaultLifecycleObserver

Callback interface for listening to LifecycleOwner state changes.

HasDefaultViewModelProviderFactory

Interface that marks a ViewModelStoreOwner as having a default ViewModelProvider.Factory for use with ViewModelProvider.

LifecycleEventObserver

Class that can receive any lifecycle change and dispatch it to the receiver.

LifecycleObserver

Marks a class as a LifecycleObserver.

LifecycleOwner

A class that has an Android lifecycle.

LifecycleRegistryOwner

This interface is deprecated.

Use androidx.appcompat.app.AppCompatActivity which extends LifecycleOwner, so there are no use cases for this class.

LiveDataScope

Interface that allows controlling a LiveData from a coroutine block.

Observer

A simple callback that can receive from LiveData.

ViewModelProvider.Factory

Implementations of Factory interface are responsible to instantiate ViewModels.

ViewModelStoreOwner

A scope that owns ViewModelStore.

Classes

AbstractSavedStateViewModelFactory

Skeleton of androidx.lifecycle.ViewModelProvider.KeyedFactory that creates SavedStateHandle for every requested ViewModel.

AndroidViewModel

Application context aware ViewModel.

Lifecycle

Defines an object that has an Android Lifecycle.

LifecycleCoroutineScope

CoroutineScope tied to a Lifecycle and Dispatchers.Main.immediate

LifecycleRegistry

An implementation of Lifecycle that can handle multiple observers.

LifecycleService

A Service that is also a LifecycleOwner.

LiveData

LiveData is a data holder class that can be observed within a given lifecycle.

MediatorLiveData

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

MutableLiveData

LiveData which publicly exposes setValue and postValue method.

ProcessLifecycleInitializer

Initializes ProcessLifecycleOwner using androidx.startup.

ProcessLifecycleOwner

Class that provides lifecycle for the whole application process.

SavedStateHandle

A handle to saved state passed down to androidx.lifecycle.ViewModel.

SavedStateViewModelFactory

androidx.lifecycle.ViewModelProvider.Factory that can create ViewModels accessing and contributing to a saved state via SavedStateHandle received in a constructor.

ServiceLifecycleDispatcher

Helper class to dispatch lifecycle events for a Service.

ViewModel

ViewModel is a class that is responsible for preparing and managing the data for an Activity or a Fragment.

ViewModelLazy

An implementation of Lazy used by androidx.fragment.app.Fragment.viewModels and androidx.activity.ComponentActivity.viewmodels.

ViewModelProvider

A utility class that provides ViewModels for a scope.

ViewModelProvider.AndroidViewModelFactory

Factory which may create AndroidViewModel and ViewModel, which have an empty constructor.

ViewModelProvider.NewInstanceFactory

Simple factory, which calls empty constructor on the give class.

ViewModelProviders

This class is deprecated.

Use the constructors for ViewModelProvider directly.

ViewModelProviders.DefaultFactory

This class is deprecated.

Use ViewModelProvider.AndroidViewModelFactory

ViewModelStore

Class to store ViewModels.

ViewModelStores

This class is deprecated.

Use getViewModelStore or getViewModelStore to retrieve a ViewModelStore directly from activities and fragments.

Exceptions

LifecycleDestroyedException

A CancellationException that indicates that the Lifecycle associated with an operation reached the Lifecycle.State.DESTROYED state before the operation could complete.

Annotations

OnLifecycleEvent

This annotation is deprecated.

This annotation required the usage of code generation or reflection, which should be avoided.

Enums

Lifecycle.Event
Lifecycle.State

Lifecycle states.

Top-level functions summary

LiveData<T>
<T : Any?> liveData(
    context: CoroutineContext,
    timeoutInMs: Long,
    block: suspend LiveDataScope<T>.() -> Unit
)

Builds a LiveData that has values yielded from the given block that executes on a LiveDataScope.

LiveData<T>
@RequiresApi(value = 26)
<T : Any?> liveData(
    timeout: Duration,
    context: CoroutineContext,
    block: suspend LiveDataScope<T>.() -> Unit
)

Builds a LiveData that has values yielded from the given block that executes on a LiveDataScope.

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

Adapts the given LiveData stream to a ReactiveStreams Publisher.

Extension functions summary

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.

LiveData<T>
<T : Any?> Flow<T>.asLiveData(context: CoroutineContext, timeoutInMs: Long)

Creates a LiveData that has values collected from the origin Flow.

LiveData<T>
@RequiresApi(value = 26)
<T : Any?> Flow<T>.asLiveData(timeout: Duration, context: CoroutineContext)

Creates a LiveData that has values collected from the origin Flow.

SavedStateHandle

Creates SavedStateHandle that can be used in your ViewModels

LiveData<X>

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

Unit

Enables the support of SavedStateHandle in a component.

LifecycleOwner?

Retrieve the LifecycleOwner responsible for managing the given View.

ViewModelStoreOwner?

Retrieve the ViewModelStoreOwner associated with the given View.

Flow<T>
<T : Any?> Flow<T>.flowWithLifecycle(
    lifecycle: Lifecycle,
    minActiveState: Lifecycle.State
)

Flow operator that emits values from this upstream Flow when the lifecycle is at least at minActiveState state.

inline VM

Returns an existing ViewModel or creates a new one in the scope (usually, a fragment or an activity), associated with this ViewModelProvider.

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.

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.

suspend Unit
Lifecycle.repeatOnLifecycle(
    state: Lifecycle.State,
    block: suspend CoroutineScope.() -> Unit
)

Runs the given block in a new coroutine when this Lifecycle is at least at state and suspends the execution until this Lifecycle is Lifecycle.State.DESTROYED.

suspend Unit
LifecycleOwner.repeatOnLifecycle(
    state: Lifecycle.State,
    block: suspend CoroutineScope.() -> Unit
)

LifecycleOwner's extension function for Lifecycle.repeatOnLifecycle to allow an easier call to the API from LifecycleOwners such as Activities and Fragments.

Unit

Set the LifecycleOwner responsible for managing the given View.

Unit

Set the ViewModelStoreOwner associated with the given View.

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.

LiveData<T>
<T : Any?> Publisher<T>.toLiveData()

Creates an observable LiveData stream from a ReactiveStreams Publisher}.

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

Adapts the given LiveData stream to a ReactiveStreams Publisher.

suspend T
<T : Any?> LifecycleOwner.whenCreated(block: suspend CoroutineScope.() -> T)

This function is deprecated. whenCreated has been deprecated because it runs the block on a pausing dispatcher that suspends, rather than cancels work when the lifecycle state goes below the given state.

suspend T
<T : Any?> Lifecycle.whenCreated(block: suspend CoroutineScope.() -> T)

This function is deprecated. whenCreated has been deprecated because it runs the block on a pausing dispatcher that suspends, rather than cancels work when the lifecycle state goes below the given state.

suspend T
<T : Any?> LifecycleOwner.whenResumed(block: suspend CoroutineScope.() -> T)

This function is deprecated. whenResumed has been deprecated because it runs the block on a pausing dispatcher that suspends, rather than cancels work when the lifecycle state goes below the given state.

suspend T
<T : Any?> Lifecycle.whenResumed(block: suspend CoroutineScope.() -> T)

This function is deprecated. whenResumed has been deprecated because it runs the block on a pausing dispatcher that suspends, rather than cancels work when the lifecycle state goes below the given state.

suspend T
<T : Any?> LifecycleOwner.whenStarted(block: suspend CoroutineScope.() -> T)

This function is deprecated. whenStarted has been deprecated because it runs the block on a pausing dispatcher that suspends, rather than cancels work when the lifecycle state goes below the given state.

suspend T
<T : Any?> Lifecycle.whenStarted(block: suspend CoroutineScope.() -> T)

This function is deprecated. whenStarted has been deprecated because it runs the block on a pausing dispatcher that suspends, rather than cancels work when the lifecycle state goes below the given state.

suspend T
<T : Any?> Lifecycle.whenStateAtLeast(
    minState: Lifecycle.State,
    block: suspend CoroutineScope.() -> T
)

This function is deprecated. whenStateAtLeast has been deprecated because it runs the block on a pausing dispatcher that suspends, rather than cancels work when the lifecycle state goes below the given state.

suspend inline R
<R : Any?> Lifecycle.withCreated(crossinline block: () -> R)

Run block with this Lifecycle in a Lifecycle.State of at least Lifecycle.State.CREATED and resume with the result.

suspend inline R
<R : Any?> LifecycleOwner.withCreated(crossinline block: () -> R)

Run block with this LifecycleOwner's Lifecycle in a Lifecycle.State of at least Lifecycle.State.CREATED and resume with the result.

suspend inline R
<R : Any?> Lifecycle.withResumed(crossinline block: () -> R)

Run block with this Lifecycle in a Lifecycle.State of at least Lifecycle.State.RESUMED and resume with the result.

suspend inline R
<R : Any?> LifecycleOwner.withResumed(crossinline block: () -> R)

Run block with this LifecycleOwner's Lifecycle in a Lifecycle.State of at least Lifecycle.State.RESUMED and resume with the result.

suspend inline R
<R : Any?> Lifecycle.withStarted(crossinline block: () -> R)

Run block with this Lifecycle in a Lifecycle.State of at least Lifecycle.State.STARTED and resume with the result.

suspend inline R
<R : Any?> LifecycleOwner.withStarted(crossinline block: () -> R)

Run block with this LifecycleOwner's Lifecycle in a Lifecycle.State of at least Lifecycle.State.STARTED and resume with the result.

suspend inline R
<R : Any?> Lifecycle.withStateAtLeast(
    state: Lifecycle.State,
    crossinline block: () -> R
)

Run block with this Lifecycle in a Lifecycle.State of at least state and resume with the result.

suspend inline R
<R : Any?> LifecycleOwner.withStateAtLeast(
    state: Lifecycle.State,
    crossinline block: () -> R
)

Run block with this LifecycleOwner's Lifecycle in a Lifecycle.State of at least state and resume with the result.

Top-level properties summary

CreationExtras.Key<Bundle>

A key for default arguments that should be passed to SavedStateHandle if needed.

CreationExtras.Key<SavedStateRegistryOwner>

A key for SavedStateRegistryOwner that corresponds to ViewModelStoreOwner of a ViewModel that is being created.

CreationExtras.Key<ViewModelStoreOwner>

A key for ViewModelStoreOwner that is an owner of a ViewModel that is being created.

Extension properties summary

Top-level functions

fun <T : Any?> liveData(
    context: CoroutineContext = EmptyCoroutineContext,
    timeoutInMs: Long = DEFAULT_TIMEOUT,
    block: suspend LiveDataScope<T>.() -> Unit
): LiveData<T>

Builds a LiveData that has values yielded from the given block that executes on a LiveDataScope.

The block starts executing when the returned LiveData becomes active. If the LiveData becomes inactive while the block is executing, it will be cancelled after timeoutInMs milliseconds unless the LiveData becomes active again before that timeout (to gracefully handle cases like Activity rotation). Any value LiveDataScope.emited from a cancelled block will be ignored.

After a cancellation, if the LiveData becomes active again, the block will be re-executed from the beginning. If you would like to continue the operations based on where it was stopped last, you can use the LiveDataScope.latestValue function to get the last LiveDataScope.emited value.

If the block completes successfully or is cancelled due to reasons other than LiveData becoming inactive, it will not be re-executed even after LiveData goes through active inactive cycle.

As a best practice, it is important for the block to cooperate in cancellation. See kotlin coroutines documentation for details https://kotlinlang.org/docs/reference/coroutines/cancellation-and-timeouts.html.

The timeoutInMs can be changed to fit different use cases better, for example increasing it will give more time to the block to complete even if LiveData is inactive. It is good for cases when block is finite (meaning it can complete successfully) and is costly to restart. Otherwise if a block is cheap to restart, decreasing the timeoutInMs value will allow to yield less values that aren't consumed by anything.

// a simple LiveData that receives value 3, 3 seconds after being observed for the first time.
val data : LiveData<Int> = liveData {
delay(3000)
emit(3)
}


// a LiveData that fetches a `User` object based on a `userId` and refreshes it every 30 seconds
// as long as it is observed
val userId : LiveData<String> = ...
val user = userId.switchMap { id ->
liveData {
while(true) {
// note that `while(true)` is fine because the `delay(30_000)` below will cooperate in
// cancellation if LiveData is not actively observed anymore
val data = api.fetch(id) // errors are ignored for brevity
emit(data)
delay(30_000)
}
}
}

// A retrying data fetcher with doubling back-off
val user = liveData {
var backOffTime = 1_000
var succeeded = false
while(!succeeded) {
try {
emit(api.fetch(id))
succeeded = true
} catch(ioError : IOException) {
delay(backOffTime)
backOffTime *= minOf(backOffTime * 2, 60_000)
}
}
}

// a LiveData that tries to load the `User` from local cache first and then tries to fetch
// from the server and also yields the updated value
val user = liveData {
// dispatch loading first
emit(LOADING(id))
// check local storage
val cached = cache.loadUser(id)
if (cached != null) {
emit(cached)
}
if (cached == null || cached.isStale()) {
val fresh = api.fetch(id) // errors are ignored for brevity
cache.save(fresh)
emit(fresh)
}
}

// a LiveData that immediately receives a LiveData<User> from the database and yields it as a
// source but also tries to back-fill the database from the server
val user = liveData {
val fromDb: LiveData<User> = roomDatabase.loadUser(id)
emitSource(fromDb)
val updated = api.fetch(id) // errors are ignored for brevity
// Since we are using Room here, updating the database will update the `fromDb` LiveData
// that was obtained above. See Room's documentation for more details.
// https://developer.android.com/training/data-storage/room/accessing-data#query-observable
roomDatabase.insert(updated)
}
Parameters
context: CoroutineContext = EmptyCoroutineContext

The CoroutineContext to run the given block in. Defaults to EmptyCoroutineContext combined with Dispatchers.Main.immediate

timeoutInMs: Long = DEFAULT_TIMEOUT

The timeout in ms before cancelling the block if there are no active observers (LiveData.hasActiveObservers. Defaults to DEFAULT_TIMEOUT.

block: suspend LiveDataScope<T>.() -> Unit

The block to run when the LiveData has active observers.

@RequiresApi(value = 26)
fun <T : Any?> liveData(
    timeout: Duration,
    context: CoroutineContext = EmptyCoroutineContext,
    block: suspend LiveDataScope<T>.() -> Unit
): LiveData<T>

Builds a LiveData that has values yielded from the given block that executes on a LiveDataScope.

The block starts executing when the returned LiveData becomes active. If the LiveData becomes inactive while the block is executing, it will be cancelled after the timeout duration unless the LiveData becomes active again before that timeout (to gracefully handle cases like Activity rotation). Any value LiveDataScope.emited from a cancelled block will be ignored.

After a cancellation, if the LiveData becomes active again, the block will be re-executed from the beginning. If you would like to continue the operations based on where it was stopped last, you can use the LiveDataScope.latestValue function to get the last LiveDataScope.emited value.

If the block completes successfully or is cancelled due to reasons other than LiveData becoming inactive, it will not be re-executed even after LiveData goes through active inactive cycle.

As a best practice, it is important for the block to cooperate in cancellation. See kotlin coroutines documentation for details https://kotlinlang.org/docs/reference/coroutines/cancellation-and-timeouts.html.

The timeout can be changed to fit different use cases better, for example increasing it will give more time to the block to complete even if LiveData is inactive. It is good for cases when block is finite (meaning it can complete successfully) and is costly to restart. Otherwise if a block is cheap to restart, decreasing the timeout value will allow to yield less values that aren't consumed by anything.

// a simple LiveData that receives value 3, 3 seconds after being observed for the first time.
val data : LiveData<Int> = liveData {
delay(3000)
emit(3)
}


// a LiveData that fetches a `User` object based on a `userId` and refreshes it every 30 seconds
// as long as it is observed
val userId : LiveData<String> = ...
val user = userId.switchMap { id ->
liveData {
while(true) {
// note that `while(true)` is fine because the `delay(30_000)` below will cooperate in
// cancellation if LiveData is not actively observed anymore
val data = api.fetch(id) // errors are ignored for brevity
emit(data)
delay(30_000)
}
}
}

// A retrying data fetcher with doubling back-off
val user = liveData {
var backOffTime = 1_000
var succeeded = false
while(!succeeded) {
try {
emit(api.fetch(id))
succeeded = true
} catch(ioError : IOException) {
delay(backOffTime)
backOffTime *= minOf(backOffTime * 2, 60_000)
}
}
}

// a LiveData that tries to load the `User` from local cache first and then tries to fetch
// from the server and also yields the updated value
val user = liveData {
// dispatch loading first
emit(LOADING(id))
// check local storage
val cached = cache.loadUser(id)
if (cached != null) {
emit(cached)
}
if (cached == null || cached.isStale()) {
val fresh = api.fetch(id) // errors are ignored for brevity
cache.save(fresh)
emit(fresh)
}
}

// a LiveData that immediately receives a LiveData<User> from the database and yields it as a
// source but also tries to back-fill the database from the server
val user = liveData {
val fromDb: LiveData<User> = roomDatabase.loadUser(id)
emitSource(fromDb)
val updated = api.fetch(id) // errors are ignored for brevity
// Since we are using Room here, updating the database will update the `fromDb` LiveData
// that was obtained above. See Room's documentation for more details.
// https://developer.android.com/training/data-storage/room/accessing-data#query-observable
roomDatabase.insert(updated)
}
Parameters
timeout: Duration

The timeout duration before cancelling the block if there are no active observers (LiveData.hasActiveObservers.

context: CoroutineContext = EmptyCoroutineContext

The CoroutineContext to run the given block in. Defaults to EmptyCoroutineContext combined with Dispatchers.Main.immediate.

block: suspend LiveDataScope<T>.() -> Unit

The block to run when the LiveData has active observers.

fun <T : Any?> toPublisher(lifecycle: LifecycleOwner, liveData: LiveData<T>): 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.

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.

fun <T : Any?> Flow<T>.asLiveData(
    context: CoroutineContext = EmptyCoroutineContext,
    timeoutInMs: Long = DEFAULT_TIMEOUT
): LiveData<T>

Creates a LiveData that has values collected from the origin Flow.

If the origin Flow is a StateFlow, then the initial value will be populated to the LiveData's value field on the main thread.

The upstream flow collection starts when the returned LiveData becomes active (LiveData.onActive). If the LiveData becomes inactive (LiveData.onInactive) while the flow has not completed, the flow collection will be cancelled after timeoutInMs milliseconds unless the LiveData becomes active again before that timeout (to gracefully handle cases like Activity rotation).

After a cancellation, if the LiveData becomes active again, the upstream flow collection will be re-executed.

If the upstream flow completes successfully or is cancelled due to reasons other than LiveData becoming inactive, it will not be re-collected even after LiveData goes through active inactive cycle.

If flow completes with an exception, then exception will be delivered to the CoroutineExceptionHandler of provided context. By default EmptyCoroutineContext is used to so an exception will be delivered to main's thread UncaughtExceptionHandler. If your flow upstream is expected to throw, you can use catch operator on upstream flow to emit a helpful error object.

The timeoutInMs can be changed to fit different use cases better, for example increasing it will give more time to flow to complete before being canceled and is good for finite flows that are costly to restart. Otherwise if a flow is cheap to restart decreasing the timeoutInMs value will allow to produce less values that aren't consumed by anything.

Parameters
context: CoroutineContext = EmptyCoroutineContext

The CoroutineContext to collect the upstream flow in. Defaults to EmptyCoroutineContext combined with Dispatchers.Main.immediate

timeoutInMs: Long = DEFAULT_TIMEOUT

The timeout in ms before cancelling the block if there are no active observers (LiveData.hasActiveObservers. Defaults to DEFAULT_TIMEOUT.

@RequiresApi(value = 26)
fun <T : Any?> Flow<T>.asLiveData(
    timeout: Duration,
    context: CoroutineContext = EmptyCoroutineContext
): LiveData<T>

Creates a LiveData that has values collected from the origin Flow.

The upstream flow collection starts when the returned LiveData becomes active (LiveData.onActive). If the LiveData becomes inactive (LiveData.onInactive) while the flow has not completed, the flow collection will be cancelled after timeout unless the LiveData becomes active again before that timeout (to gracefully handle cases like Activity rotation).

After a cancellation, if the LiveData becomes active again, the upstream flow collection will be re-executed.

If the upstream flow completes successfully or is cancelled due to reasons other than LiveData becoming inactive, it will not be re-collected even after LiveData goes through active inactive cycle.

If flow completes with an exception, then exception will be delivered to the CoroutineExceptionHandler of provided context. By default EmptyCoroutineContext is used to so an exception will be delivered to main's thread UncaughtExceptionHandler. If your flow upstream is expected to throw, you can use catch operator on upstream flow to emit a helpful error object.

The timeout can be changed to fit different use cases better, for example increasing it will give more time to flow to complete before being canceled and is good for finite flows that are costly to restart. Otherwise if a flow is cheap to restart decreasing the timeout value will allow to produce less values that aren't consumed by anything.

Parameters
timeout: Duration

The timeout in ms before cancelling the block if there are no active observers (LiveData.hasActiveObservers. Defaults to DEFAULT_TIMEOUT.

context: CoroutineContext = EmptyCoroutineContext

The CoroutineContext to collect the upstream flow in. Defaults to EmptyCoroutineContext combined with Dispatchers.Main.immediate

createSavedStateHandle

@MainThread
fun CreationExtras.createSavedStateHandle(): SavedStateHandle

Creates SavedStateHandle that can be used in your ViewModels

This function requires enableSavedStateHandles call during the component initialization. Latest versions of androidx components like ComponentActivity, Fragment, NavBackStackEntry makes this call automatically.

This CreationExtras must contain SAVED_STATE_REGISTRY_OWNER_KEY, VIEW_MODEL_STORE_OWNER_KEY and VIEW_MODEL_KEY.

Throws
kotlin.IllegalArgumentException

if this CreationExtras are missing required keys: ViewModelStoreOwnerKey, SavedStateRegistryOwnerKey, VIEW_MODEL_KEY

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

enableSavedStateHandles

@MainThread
fun <T : SavedStateRegistryOwner & ViewModelStoreOwner> T.enableSavedStateHandles(

): Unit

Enables the support of SavedStateHandle in a component.

After this method, createSavedStateHandle can be called on CreationExtras containing this SavedStateRegistryOwner / ViewModelStoreOwner.

Must be called while component is in INITIALIZED or CREATED state and before a ViewModel with SavedStateHandle is requested.

findViewTreeLifecycleOwner

fun View.findViewTreeLifecycleOwner(): LifecycleOwner?

Retrieve the LifecycleOwner responsible for managing the given View. This may be used to scope work or heavyweight resources associated with the view that may span cycles of the view becoming detached and reattached from a window.

Returns
LifecycleOwner?

The LifecycleOwner responsible for managing this view and/or some subset of its ancestors

findViewTreeViewModelStoreOwner

fun View.findViewTreeViewModelStoreOwner(): ViewModelStoreOwner?

Retrieve the ViewModelStoreOwner associated with the given View. This may be used to retain state associated with this view across configuration changes.

Returns
ViewModelStoreOwner?

The ViewModelStoreOwner associated with this view and/or some subset of its ancestors

fun <T : Any?> Flow<T>.flowWithLifecycle(
    lifecycle: Lifecycle,
    minActiveState: Lifecycle.State = Lifecycle.State.STARTED
): Flow<T>

Flow operator that emits values from this upstream Flow when the lifecycle is at least at minActiveState state. The emissions will be stopped when the lifecycle state falls below minActiveState state.

The flow will automatically start and cancel collecting from this upstream flow as the lifecycle moves in and out of the target state.

If this upstream Flow completes emitting items, flowWithLifecycle will trigger the flow collection again when the minActiveState state is reached.

This is NOT a terminal operator. This operator is usually followed by collect, or onEach and launchIn to process the emitted values.

Note: this operator creates a hot flow that only closes when the lifecycle is destroyed or the coroutine that collects from the flow is cancelled.

class MyActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
/* ... */
// Launches a coroutine that collects items from a flow when the Activity
// is at least started. It will automatically cancel when the activity is stopped and
// start collecting again whenever it's started again.
lifecycleScope.launch {
flow
.flowWithLifecycle(lifecycle, Lifecycle.State.STARTED)
.collect {
// Consume flow emissions
}
}
}
}

flowWithLifecycle cancels the upstream Flow when lifecycle falls below minActiveState state. However, the downstream Flow will be active without receiving any emissions as long as the scope used to collect the Flow is active. As such, please take care when using this function in an operator chain, as the order of the operators matters. For example, flow1.flowWithLifecycle(lifecycle).combine(flow2) behaves differently than flow1.combine(flow2).flowWithLifecycle(lifecycle). The former continues to combine both flows even when lifecycle falls below minActiveState state whereas the combination is cancelled in the latter case.

Warning: Lifecycle.State.INITIALIZED is not allowed in this API. Passing it as a parameter will throw an IllegalArgumentException.

Tip: If multiple flows need to be collected using flowWithLifecycle, consider using the Lifecycle.repeatOnLifecycle API to collect from all of them using a different launch per flow instead. That's more efficient and consumes less resources as no hot flows are created.

Parameters
lifecycle: Lifecycle

The Lifecycle where the restarting collecting from this flow work will be kept alive.

minActiveState: Lifecycle.State = Lifecycle.State.STARTED

Lifecycle.State in which the upstream flow gets collected. The collection will stop if the lifecycle falls below that state, and will restart if it's in that state again.

Returns
Flow<T>

Flow that only emits items from this upstream flow when the lifecycle is at least in the minActiveState.

@MainThread
inline fun <VM : ViewModel> ViewModelProvider.get(): VM

Returns an existing ViewModel or creates a new one in the scope (usually, a fragment or an activity), associated with this ViewModelProvider.

See also
get

(Class)

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

observe

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

repeatOnLifecycle

suspend fun Lifecycle.repeatOnLifecycle(
    state: Lifecycle.State,
    block: suspend CoroutineScope.() -> Unit
): Unit

Runs the given block in a new coroutine when this Lifecycle is at least at state and suspends the execution until this Lifecycle is Lifecycle.State.DESTROYED.

The block will cancel and re-launch as the lifecycle moves in and out of the target state.

class MyActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
/* ... */
// Runs the block of code in a coroutine when the lifecycle is at least STARTED.
// The coroutine will be cancelled when the ON_STOP event happens and will
// restart executing if the lifecycle receives the ON_START event again.
lifecycleScope.launch {
lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
uiStateFlow.collect { uiState ->
updateUi(uiState)
}
}
}
}
}

The best practice is to call this function when the lifecycle is initialized. For example, onCreate in an Activity, or onViewCreated in a Fragment. Otherwise, multiple repeating coroutines doing the same could be created and be executed at the same time.

Repeated invocations of block will run serially, that is they will always wait for the previous invocation to fully finish before re-starting execution as the state moves in and out of the required state.

Warning: Lifecycle.State.INITIALIZED is not allowed in this API. Passing it as a parameter will throw an IllegalArgumentException.

Parameters
state: Lifecycle.State

Lifecycle.State in which block runs in a new coroutine. That coroutine will cancel if the lifecycle falls below that state, and will restart if it's in that state again.

block: suspend CoroutineScope.() -> Unit

The block to run when the lifecycle is at least in state state.

repeatOnLifecycle

suspend fun LifecycleOwner.repeatOnLifecycle(
    state: Lifecycle.State,
    block: suspend CoroutineScope.() -> Unit
): Unit

LifecycleOwner's extension function for Lifecycle.repeatOnLifecycle to allow an easier call to the API from LifecycleOwners such as Activities and Fragments.

class MyActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
/* ... */
// Runs the block of code in a coroutine when the lifecycle is at least STARTED.
// The coroutine will be cancelled when the ON_STOP event happens and will
// restart executing if the lifecycle receives the ON_START event again.
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
uiStateFlow.collect { uiState ->
updateUi(uiState)
}
}
}
}
}

setViewTreeLifecycleOwner

fun View.setViewTreeLifecycleOwner(lifecycleOwner: LifecycleOwner?): Unit

Set the LifecycleOwner responsible for managing the given View. Calls to get from this view or descendants will return lifecycleOwner.

This should only be called by constructs such as activities or fragments that manage a view tree and reflect their own lifecycle through a LifecycleOwner. Callers should only set a LifecycleOwner that will be stable. The associated lifecycle should report that it is destroyed if the view tree is removed and is not guaranteed to later become reattached to a window.

Parameters
lifecycleOwner: LifecycleOwner?

LifecycleOwner representing the manager of the given view

setViewTreeViewModelStoreOwner

fun View.setViewTreeViewModelStoreOwner(
    viewModelStoreOwner: ViewModelStoreOwner?
): Unit

Set the ViewModelStoreOwner associated with the given View. Calls to get from this view or descendants will return viewModelStoreOwner.

This should only be called by constructs such as activities or fragments that manage a view tree and retain state through a ViewModelStoreOwner. Callers should only set a ViewModelStoreOwner that will be stable. The associated ViewModelStore should be cleared if the view tree is removed and is not guaranteed to later become reattached to a window.

Parameters
viewModelStoreOwner: ViewModelStoreOwner?

ViewModelStoreOwner associated with the given view

@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

fun <T : Any?> Publisher<T>.toLiveData(): LiveData<T>

Creates an observable LiveData stream from a ReactiveStreams Publisher}.

When the LiveData becomes active, it subscribes to the emissions from the Publisher.

When the LiveData becomes inactive, the subscription is cleared. LiveData holds the last value emitted by the Publisher when the LiveData was active.

Therefore, in the case of a hot RxJava Observable, when a new LiveData Observer is added, it will automatically notify with the last value held in LiveData, which might not be the last value emitted by the Publisher.

Note that LiveData does NOT handle errors and it expects that errors are treated as states in the data that's held. In case of an error being emitted by the publisher, an error will be propagated to the main thread and the app will crash.

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.

suspend fun <T : Any?> LifecycleOwner.whenCreated(block: suspend CoroutineScope.() -> T): T

Runs the given block when the LifecycleOwner's Lifecycle is at least in Lifecycle.State.CREATED state.

See also
whenStateAtLeast

for details

suspend fun <T : Any?> Lifecycle.whenCreated(block: suspend CoroutineScope.() -> T): T

Runs the given block when the Lifecycle is at least in Lifecycle.State.CREATED state.

See also
whenStateAtLeast

for details

suspend fun <T : Any?> LifecycleOwner.whenResumed(block: suspend CoroutineScope.() -> T): T

Runs the given block when the LifecycleOwner's Lifecycle is at least in Lifecycle.State.RESUMED state.

See also
whenStateAtLeast

for details

suspend fun <T : Any?> Lifecycle.whenResumed(block: suspend CoroutineScope.() -> T): T

Runs the given block when the Lifecycle is at least in Lifecycle.State.RESUMED state.

See also
whenStateAtLeast

for details

suspend fun <T : Any?> LifecycleOwner.whenStarted(block: suspend CoroutineScope.() -> T): T

Runs the given block when the LifecycleOwner's Lifecycle is at least in Lifecycle.State.STARTED state.

See also
whenStateAtLeast

for details

suspend fun <T : Any?> Lifecycle.whenStarted(block: suspend CoroutineScope.() -> T): T

Runs the given block when the Lifecycle is at least in Lifecycle.State.STARTED state.

See also
whenStateAtLeast

for details

suspend fun <T : Any?> Lifecycle.whenStateAtLeast(
    minState: Lifecycle.State,
    block: suspend CoroutineScope.() -> T
): T

Runs the given block on a CoroutineDispatcher that executes the block on the main thread and suspends the execution unless the Lifecycle's state is at least minState.

If the Lifecycle moves to a lesser state while the block is running, the block will be suspended until the Lifecycle reaches to a state greater or equal to minState.

Note that this won't effect any sub coroutine if they use a different CoroutineDispatcher. However, the block will not resume execution when the sub coroutine finishes unless the Lifecycle is at least in minState.

If the Lifecycle is destroyed while the block is suspended, the block will be cancelled which will also cancel any child coroutine launched inside the block.

If you have a try finally block in your code, the finally might run after the Lifecycle moves outside the desired state. It is recommended to check the Lifecycle.getCurrentState before accessing the UI. Similarly, if you have a catch statement that might catch CancellationException, you should check the Lifecycle.getCurrentState before accessing the UI. See the sample below for more details.

// running a block of code only if lifecycle is STARTED
viewLifecycle.whenStateAtLeast(Lifecycle.State.STARTED) {
// here, we are on the main thread and view lifecycle is guaranteed to be STARTED or RESUMED.
// We can safely access our views.
loadingBar.visibility = View.VISIBLE
try {
// we can call any suspend function
val data = withContext(Dispatchers.IO) {
// this will run in IO thread pool. It will keep running as long as Lifecycle
// is not DESTROYED. If it is destroyed, this coroutine will be cancelled as well.
// However, we CANNOT access Views here.

// We are using withContext(Dispatchers.IO) here just for demonstration purposes.
// Such code should live in your business logic classes and your UI should use a
// ViewModel (or similar) to access it.
api.getUser()
}
// this line will execute on the main thread and only if the lifecycle is in at least
// STARTED state (STARTED is the parameter we've passed to whenStateAtLeast)
// Because of this guarantee, we can safely access the UI again.
loadingBar.visibility = View.GONE
nameTextView.text = user.name
lastNameTextView.text = user.lastName
} catch(ex : UserNotFoundException) {
// same as above, this code can safely access UI elements because it only runs if
// view lifecycle is at least STARTED
loadingBar.visibility = View.GONE
showErrorDialog(ex)
} catch(th : Throwable) {
// Unlike the catch statement above, this catch statements it too generic and might
// also catch the CancellationException. Before accessing UI, you should check isActive
// or lifecycle state
if (viewLifecycle.currentState >= Lifecycle.State.STARTED) {
// here you can access the view because you've checked the coroutine is active
}
} finally {
// in case of cancellation, this line might run even if the Lifecycle is not DESTROYED.
// You cannot access Views here unless you check `isActive` or lifecycle state
if (viewLifecycle.currentState >= Lifecycle.State.STARTED) {
// safe to access views
} else {
// not safe to access views
}
}
}
Parameters
minState: Lifecycle.State

The desired minimum state to run the block.

block: suspend CoroutineScope.() -> T

The block to run when the lifecycle is at least in minState.

Returns
T The return value of the [block]
suspend inline fun <R : Any?> Lifecycle.withCreated(crossinline block: () -> R): R

Run block with this Lifecycle in a Lifecycle.State of at least Lifecycle.State.CREATED and resume with the result. Throws the CancellationException if the lifecycle has reached Lifecycle.State.DESTROYED by the time of the call or before block is able to run.

suspend inline fun <R : Any?> LifecycleOwner.withCreated(crossinline block: () -> R): R

Run block with this LifecycleOwner's Lifecycle in a Lifecycle.State of at least Lifecycle.State.CREATED and resume with the result. Throws the CancellationException if the lifecycle has reached Lifecycle.State.DESTROYED by the time of the call or before block is able to run.

suspend inline fun <R : Any?> Lifecycle.withResumed(crossinline block: () -> R): R

Run block with this Lifecycle in a Lifecycle.State of at least Lifecycle.State.RESUMED and resume with the result. Throws the CancellationException if the lifecycle has reached Lifecycle.State.DESTROYED by the time of the call or before block is able to run.

suspend inline fun <R : Any?> LifecycleOwner.withResumed(crossinline block: () -> R): R

Run block with this LifecycleOwner's Lifecycle in a Lifecycle.State of at least Lifecycle.State.RESUMED and resume with the result. Throws the CancellationException if the lifecycle has reached Lifecycle.State.DESTROYED by the time of the call or before block is able to run.

suspend inline fun <R : Any?> Lifecycle.withStarted(crossinline block: () -> R): R

Run block with this Lifecycle in a Lifecycle.State of at least Lifecycle.State.STARTED and resume with the result. Throws the CancellationException if the lifecycle has reached Lifecycle.State.DESTROYED by the time of the call or before block is able to run.

suspend inline fun <R : Any?> LifecycleOwner.withStarted(crossinline block: () -> R): R

Run block with this LifecycleOwner's Lifecycle in a Lifecycle.State of at least Lifecycle.State.STARTED and resume with the result. Throws the CancellationException if the lifecycle has reached Lifecycle.State.DESTROYED by the time of the call or before block is able to run.

suspend inline fun <R : Any?> Lifecycle.withStateAtLeast(
    state: Lifecycle.State,
    crossinline block: () -> R
): R

Run block with this Lifecycle in a Lifecycle.State of at least state and resume with the result. Throws the CancellationException if the lifecycle has reached Lifecycle.State.DESTROYED by the time of the call or before block is able to run.

suspend inline fun <R : Any?> LifecycleOwner.withStateAtLeast(
    state: Lifecycle.State,
    crossinline block: () -> R
): R

Run block with this LifecycleOwner's Lifecycle in a Lifecycle.State of at least state and resume with the result. Throws the CancellationException if the lifecycle has reached Lifecycle.State.DESTROYED by the time of the call or before block is able to run.

Top-level properties

val DEFAULT_ARGS_KEYCreationExtras.Key<Bundle>

A key for default arguments that should be passed to SavedStateHandle if needed.

SAVED_STATE_REGISTRY_OWNER_KEY

val SAVED_STATE_REGISTRY_OWNER_KEYCreationExtras.Key<SavedStateRegistryOwner>

A key for SavedStateRegistryOwner that corresponds to ViewModelStoreOwner of a ViewModel that is being created.

VIEW_MODEL_STORE_OWNER_KEY

val VIEW_MODEL_STORE_OWNER_KEYCreationExtras.Key<ViewModelStoreOwner>

A key for ViewModelStoreOwner that is an owner of a ViewModel that is being created.

Extension properties

coroutineScope

val Lifecycle.coroutineScopeLifecycleCoroutineScope

CoroutineScope tied to this Lifecycle.

This scope will be cancelled when the Lifecycle is destroyed.

This scope is bound to Dispatchers.Main.immediate

val Lifecycle.eventFlowFlow<Lifecycle.Event>

Creates a Flow of Events containing values dispatched by this Lifecycle.

lifecycleScope

val LifecycleOwner.lifecycleScopeLifecycleCoroutineScope

CoroutineScope tied to this LifecycleOwner's Lifecycle.

This scope will be cancelled when the Lifecycle is destroyed.

This scope is bound to Dispatchers.Main.immediate.

val ViewModel.viewModelScopeCoroutineScope

CoroutineScope tied to this ViewModel. This scope will be canceled when ViewModel will be cleared, i.e ViewModel.onCleared is called

This scope is bound to Dispatchers.Main.immediate