BackstackLifecycle
Lifecycle manager for a screen in the backstack.
Provides access to visibility status, state selection, action dispatching, and a coroutine scope tied to the entry's lifecycle. Coroutines launched via this scope are automatically cancelled when the entry is removed from the backstack.
Lifecycle Flow
Normal Navigation:
Screen added to backstack → Navigatable.onLifecycleCreated called once
Screen remains in backstack → No lifecycle events (observe visibility for changes)
Screen removed from backstack → invokeOnRemoval handlers called once, then scope cancelled
With Store.reset():
Store.reset()called → invokeOnRemoval handlers for all existing entriesObservation restarts → Navigatable.onLifecycleCreated called once for each backstack entry
Fresh lifecycle instances created with clean state
Each reset is idempotent - multiple resets follow the same pattern.
Example Usage
override suspend fun onLifecycleCreated(lifecycle: BackstackLifecycle) {
// Check current visibility
if (lifecycle.visibility.value) {
lifecycle.dispatch(MyAction.LoadData)
}
// Observe visibility changes - auto-cancelled when entry is removed
lifecycle.launch {
lifecycle.visibility.collect { isVisible ->
println("Visibility changed: $isVisible")
}
}
// Register cleanup when removed from backstack
lifecycle.invokeOnRemoval {
// `this` is StoreAccessor — non-suspend context
// Must use launch for suspend work (fire-and-forget)
launch {
val logic = selectLogic<SomeLogic>()
logic.cleanup()
dispatch(SomeAction.Removed)
}
}
}