androidx.lifecycle


Interfaces

DefaultLifecycleObserver

Callback interface for listening to LifecycleOwner state changes.

Cmn
HasDefaultViewModelProviderFactory

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

Cmn
LifecycleEventObserver

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

Cmn
LifecycleObserver

Marks a class as a LifecycleObserver.

Cmn
LifecycleOwner

A class that has an Android lifecycle.

Cmn
LifecycleRegistryOwner

This interface is deprecated.

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

android
LiveDataScope

Interface that allows controlling a LiveData from a coroutine block.

android
Observer

A simple callback that can receive from LiveData.

android
ViewModelProvider.Factory

Implementations of Factory interface are responsible to instantiate ViewModels.

Cmn
android
N
ViewModelStoreOwner

A scope that owns ViewModelStore.

Cmn

Classes

AbstractSavedStateViewModelFactory

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

android
AndroidViewModel

Application context aware ViewModel.

android
Lifecycle

Defines an object that has an Android Lifecycle. androidx.fragment.app.Fragment and androidx.fragment.app.FragmentActivity classes implement LifecycleOwner interface which has the LifecycleOwner.getLifecycle method to access the Lifecycle.

Cmn
LifecycleCoroutineScope

CoroutineScope tied to a Lifecycle and Dispatchers.Main.immediate

Cmn
android
N
LifecycleRegistry

An implementation of Lifecycle that can handle multiple observers.

Cmn
android
N
LifecycleService

A Service that is also a LifecycleOwner.

android
LiveData

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

android
MediatorLiveData

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

android
MutableLiveData

LiveData which publicly exposes setValue and postValue method.

android
ProcessLifecycleInitializer

Initializes ProcessLifecycleOwner using androidx.startup.

android
ProcessLifecycleOwner

Class that provides lifecycle for the whole application process.

android
SavedStateHandle

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

Cmn
android
SavedStateViewModelFactory

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

Cmn
android
ServiceLifecycleDispatcher

Helper class to dispatch lifecycle events for a Service.

android
ViewModel

ViewModel is a class that is responsible for preparing and managing the data for an androidx.activity.ComponentActivity or a androidx.fragment.app.Fragment.

Cmn
android
N
ViewModelLazy

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

Cmn
ViewModelProvider

A utility class that provides ViewModels for a scope.

Cmn
android
N
ViewModelProvider.NewInstanceFactory

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

android
ViewModelProviders

This class is deprecated.

Use the constructors for ViewModelProvider directly.

android
ViewModelProviders.DefaultFactory

This class is deprecated.

Use ViewModelProvider.AndroidViewModelFactory

android
ViewModelStore

Class to store ViewModels.

Cmn
ViewModelStores

This class is deprecated.

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

android

Exceptions

LifecycleDestroyedException

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

Cmn

Objects

Annotations

OnLifecycleEvent

This annotation is deprecated.

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

android

Enums

Lifecycle.Event
Cmn
Lifecycle.State

Lifecycle states.

Cmn

Type aliases

AtomicReference
android

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.

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

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

This function is deprecated. Use the extension method `liveData.toPublisher(lifecycleOwner)` instead.

android

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.

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

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

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

android
SavedStateHandle

Creates SavedStateHandle that can be used in your ViewModels

Cmn
LiveData<X>

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

android
Unit

Enables the support of SavedStateHandle in a component.

Cmn
LifecycleOwner?

Retrieve the LifecycleOwner responsible for managing the given View.

android
ViewModelStoreOwner?

Retrieve the ViewModelStoreOwner associated with the given View.

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

Cmn
inline VM

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

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

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

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

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

Cmn
inline ReadWriteProperty<Any?, T>
<T : Any> SavedStateHandle.saved(noinline init: () -> T)

Returns a property delegate that uses SavedStateHandle to save and restore a value of type T with fully qualified property or variable name as key and the default serializer.

Cmn
inline ReadWriteProperty<Any?, T>
<T : Any> SavedStateHandle.saved(key: String, noinline init: () -> T)

Returns a property delegate that uses SavedStateHandle to save and restore a value of type T with the default serializer.

Cmn
ReadWriteProperty<Any?, T>
<T : Any> SavedStateHandle.saved(
    serializer: <Error class: unknown class><T>,
    init: () -> T
)

Returns a property delegate that uses SavedStateHandle to save and restore a value of type T with fully qualified property or variable name as key.

Cmn
ReadWriteProperty<Any?, T>
<T : Any> SavedStateHandle.saved(
    key: String,
    serializer: <Error class: unknown class><T>,
    init: () -> T
)

Returns a property delegate that uses SavedStateHandle to save and restore a value of type T.

Cmn
Unit

Set the LifecycleOwner responsible for managing the given View.

android
Unit

Set the ViewModelStoreOwner associated with the given View.

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

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

Creates an observable LiveData stream from a ReactiveStreams Publisher}.

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

Adapts the given LiveData stream to a ReactiveStreams Publisher.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Cmn

Top-level properties summary

CreationExtras.Key<SavedState>

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

Cmn
CreationExtras.Key<SavedStateRegistryOwner>

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

Cmn
CreationExtras.Key<ViewModelStoreOwner>

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

Cmn

Extension properties summary

Top-level functions

liveData

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.

toPublisher

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

asFlow

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.

asLiveData

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.

asLiveData

@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

flowWithLifecycle

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)
}
}
}
}
}
inline fun <T : Any> SavedStateHandle.saved(noinline init: () -> T): ReadWriteProperty<Any?, T>

Returns a property delegate that uses SavedStateHandle to save and restore a value of type T with fully qualified property or variable name as key and the default serializer.

@Serializable data class User(val id: Int, val name: String)
class ProfileViewModel(savedStateHandle: SavedStateHandle) : ViewModel() {
    val user by savedStateHandle.saved { User(123, "foo") }
}
Parameters
noinline init: () -> T

The function to provide the initial value of the property.

Returns
ReadWriteProperty<Any?, T>

A property delegate that manages the saving and restoring of the value.

inline fun <T : Any> SavedStateHandle.saved(key: String, noinline init: () -> T): ReadWriteProperty<Any?, T>

Returns a property delegate that uses SavedStateHandle to save and restore a value of type T with the default serializer.

@Serializable data class User(val id: Int, val name: String)
class ProfileViewModel(savedStateHandle: SavedStateHandle) : ViewModel() {
    val user by savedStateHandle.saved(key = "bar") { User(123, "foo") }
}
Parameters
key: String

The String key to use for storing the value in the SavedStateHandle.

noinline init: () -> T

The function to provide the initial value of the property.

Returns
ReadWriteProperty<Any?, T>

A property delegate that manages the saving and restoring of the value.

fun <T : Any> SavedStateHandle.saved(
    serializer: <Error class: unknown class><T>,
    init: () -> T
): ReadWriteProperty<Any?, T>

Returns a property delegate that uses SavedStateHandle to save and restore a value of type T with fully qualified property or variable name as key.

@Serializable data class User(val id: Int, val name: String)
class ProfileViewModel(savedStateHandle: SavedStateHandle) : ViewModel() {
    val user by savedStateHandle.saved(User::class.serializer()) { User(123, "foo") }
}
Parameters
serializer: <Error class: unknown class><T>

The KSerializer to use for serializing and deserializing the value.

init: () -> T

The function to provide the initial value of the property.

Returns
ReadWriteProperty<Any?, T>

A property delegate that manages the saving and restoring of the value.

fun <T : Any> SavedStateHandle.saved(
    key: String,
    serializer: <Error class: unknown class><T>,
    init: () -> T
): ReadWriteProperty<Any?, T>

Returns a property delegate that uses SavedStateHandle to save and restore a value of type T.

@Serializable data class User(val id: Int, val name: String)
class ProfileViewModel(savedStateHandle: SavedStateHandle) : ViewModel() {
    val user by
        savedStateHandle.saved(key = "bar", serializer = User::class.serializer()) {
            User(123, "foo")
        }
}
Parameters
key: String

The String key to use for storing the value in the SavedStateHandle.

serializer: <Error class: unknown class><T>

The KSerializer to use for serializing and deserializing the value.

init: () -> T

The function to provide the initial value of the property.

Returns
ReadWriteProperty<Any?, T>

A property delegate that manages the saving and restoring of the value.

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

toLiveData

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.

toPublisher

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.

whenCreated

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

whenCreated

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

whenResumed

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

whenResumed

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

whenStarted

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

whenStarted

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

whenStateAtLeast

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.

withStateAtLeast

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.

withStateAtLeast

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

DEFAULT_ARGS_KEY

val DEFAULT_ARGS_KEYCreationExtras.Key<SavedState>

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

application

val AndroidViewModel.applicationApplication

The underlying Application inside AndroidViewModel

One common hierarchy, such as KotlinViewModel <: JavaViewModel <: AndroidViewModel, exposes private property application incorrectly. It is now fixed in K2 (Kotlin language version 2.0), but not backward compatible. This inline extension will make compilations of both pre- and post- 2.0 go well.

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

viewModelScope

val ViewModel.viewModelScopeCoroutineScope

The CoroutineScope associated with this ViewModel.

The CoroutineScope.coroutineContext is configured with:

This scope is automatically cancelled when the ViewModel is cleared, and can be replaced by using the ViewModel constructor overload that takes in a viewModelScope: CoroutineScope.

For background execution, use kotlinx.coroutines.withContext to switch to appropriate dispatchers (e.g., kotlinx.coroutines.IO).

See also
onCleared