stateInDelayed
Converts a Flow to a StateFlow with a 5-second stop timeout for improved performance.
This extension function is a convenience wrapper around stateIn that uses SharingStarted.WhileSubscribed(5000L) to automatically stop the upstream flow 5 seconds after the last subscriber unsubscribes. This prevents unnecessary work when there are no active collectors.
When to Use
Use this when you want to:
Convert a cold Flow (like Room database queries) into a hot StateFlow
Keep the flow active briefly after the last subscriber leaves (e.g., during configuration changes)
Avoid restarting expensive operations during brief UI lifecycle transitions
Common Use Cases
// In a ViewModel - observe database with automatic lifecycle management
class MyViewModel(repository: MyRepository) : ViewModel() {
val users: StateFlow<List<User>> = repository.observeUsers()
.stateInDelayed(
initialValue = emptyList(),
scope = viewModelScope
)
}
// In a Repository - expose Flow as StateFlow
class MyRepository(private val database: MyDatabase) {
fun observeUsers(): Flow<List<User>> = database.userDao().observeAll()
}Why 5 Seconds?
The 5-second delay is optimal for:
Configuration changes (screen rotation) - typically complete in < 1 second
Brief app backgrounding - keeps data ready for quick return
Navigation transitions - prevents unnecessary restarts
While still stopping the flow quickly enough to avoid resource waste when the user truly leaves the screen.
Performance Benefits
// Without delay (restarts on every rotation)
val users = repository.observeUsers()
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), emptyList())
// With delay (survives rotation, avoids restart)
val users = repository.observeUsers()
.stateInDelayed(emptyList(), viewModelScope) // ← PreferredReturn
A StateFlow that replays the last emitted value to new subscribers and stays active for 5 seconds after the last subscriber unsubscribes.
Parameters
The type of values emitted by the Flow.
The initial value of the StateFlow before the first emission from the source Flow. This value is emitted immediately when the StateFlow is first collected.
The CoroutineScope in which the Flow will be collected. Typically viewModelScope. The Flow collection will be cancelled when this scope is cancelled.
See also
For the underlying implementation
For sharing strategy details