Effects coroutines and lifecycle
Effects, Coroutines, and Lifecycle Deep Dive¶
Overview¶
LaunchedEffect, DisposableEffect, and rememberCoroutineScope connect coroutines
and callback-style resources to composition lifecycle.
Core Concepts¶
LaunchedEffect: composition-scoped coroutineDisposableEffect: setup + guaranteed cleanuprememberCoroutineScope: manual event-driven launches
Runtime Internals¶
Effect jobs are attached to composition scope. Key changes trigger cancellation and restart for keyed effects.
Composition / Recomposition Flow¶
- enter composition -> start keyed effect
- key change -> cancel old job, launch new one
- leave composition -> cancel/dispose deterministically
State Management¶
Use rememberUpdatedState when effect must keep running but consume latest callback.
Code Examples¶
@Composable
fun LocationObserver(onLocation: (Location) -> Unit) {
DisposableEffect(Unit) {
val listener = startLocationUpdates(onLocation)
onDispose { listener.stop() }
}
}
Common Interview Questions¶
- Q:
LaunchedEffect(Unit)vsrememberCoroutineScope? A: Explain runtime behavior: what invalidates state, how recomposition is scoped, where side effects live, and how to verify frame stability with profiler traces. - Q: How do you avoid stale lambda capture? A: Describe data policy explicitly: freshness and invalidation rules, canonical local source, deterministic merge logic, and duplicate prevention with stable keys.
- Q: When is cleanup guaranteed? A: Answer from runtime mechanics: state ownership, recomposition triggers, effect lifecycle, and frame-time impact measured with tooling.
Production Considerations¶
- avoid unstable keys for long-lived jobs
- keep cleanup paths explicit
- use lifecycle-aware collection in screen composables
Performance Insights¶
Frequent effect restart in scroll-heavy or rapidly changing UIs can become an invisible source of overhead.
Senior-Level Insights¶
Best answers show precise cancellation semantics and justify effect API choices using lifecycle and correctness constraints.