stateIn vs shareIn
기존에 존재하는 cold stream을 hot stream으로 변환하기 위해서는 Flow의 extension function으로 stateIn과 sharedIn이 존재합니다.
// cold stream flow -> SharedFlow로 변경
fun <T> Flow<T>.shareIn(scope: CoroutineScope,
started: SharingStarted,
replay: Int = 0): SharedFlow<T>
// cold stream flow -> StateFlow로 변경
fun <T> Flow<T>.stateIn(scope: CoroutineScope,
started: SharingStarted,
initialValue: T): StateFlow<T>
// cold stream
val backendMessages: Flow<Message> = flow {
connectToBackend() // takes a lot of time
try {
while (true) {
emit(receiveMessageFromBackend())
}
} finally {
disconnectFromBackend()
}
}
// SharedFlow로 변경
val messages: SharedFlow<Message> =
backendMessages.shareIn(scope, SharingStarted.Eagerly)
-> coroutineScope과 SharingStarted param은 stateIn과 sharedIn에서 동일하게 사용됩니다. coroutineScope은 hot stream을 수행하는 coroutine을 생성할 scope을 넘겨주고, SharingStarted는 flow를 실행하는 방법을 세부적으로 조정하기 위해 사용됩니다.
SharingStarted.Eagerly
SharingStarted.Lazily
SharingStarted.WhileSubscribed
Flow lifecycle for Android
override fun onCreate(savedInstanceState: Bundle?) {
...
MainScope().launch {
testViewModel.connectionFlow.collect {
Log.i(TAG, "connectionFlow: $it")
}
}
...
}
override fun onCreate(savedInstanceState: Bundle?) {
...
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
testViewModel.connectionFlow.collect {
Log.i(TAG, "connectionFlow: $it")
}
}
}
...
}
-> activity가 onStart되는 시점이나 onPause되는 시점에 새로운 coroutine으로 시작되며, onStop 시점에 cancel됩니다.