Middle+
What unexpected problems can arise when working with coroutines in Android?
sobes.tech AI
Answer from AI
- Unexpected cancellation: A coroutine can be implicitly canceled, for example, when changing device configuration or closing an Activity/Fragment, if the lifecycle context is not managed carefully. This can lead to memory leaks or unfinished operations.
- Context propagation issues: Passing coroutine context between application layers (UI, ViewModel, Repository) requires attention. Incorrect use of context can cause UI hangs or thread blocking.
- Resource leaks on unhandled exceptions: Unhandled exceptions in child coroutines can implicitly cancel the parent, but resources allocated within the child may not be released.
- "Cold" flows (
Flow) and their lifecycle management:Flowis lazy by nature and requires active data collection. If collection is not managed properly (e.g., usingflowWithLifecycleorcollectLatest), undesirable behavior can occur during UI or lifecycle state changes. - Blocking calls: Including blocking calls (e.g., network or file operations) in a coroutine running on the main thread dispatcher (
Dispatchers.Main) will lead to ANR.
// Example of potential coroutine cancellation issue during configuration change
class MyViewModel : ViewModel() {
fun loadData() {
viewModelScope.launch {
// Long operation
delay(5000)
// If Activity is recreated during delay, this line may not execute
println("Data loaded")
}
}
}
// Example of a blocking call on the Main dispatcher
import kotlinx.coroutines.*
fun performBlockingOperation() {
runBlocking { // Do not use in UI thread!
delay(1000) // Blocks the thread
}
}
// Should be like this:
fun performNonBlockingOperation() {
CoroutineScope(Dispatchers.Default).launch {
delay(1000) // Does not block the main thread
}
}