When I use Channel and convert it to Android LiveData by consumeAsFlow().asLiveData() in Android ViewModel like this
class MainViewModel : ViewModel() {
private val channel = Channel<Int>()
val channelLiveData = channel.consumeAsFlow().asLiveData()
}
Then subscribe it in the Android Activity's onCreate
viewModel.channelLiveData.observe(this) {
//...
}
There's an exception raised when I press home button to home screen(Lifecycle stopped) for a few seconds, and then back to app:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.diousk.channellivedataissue, PID: 20520
java.lang.IllegalStateException: ReceiveChannel.consumeAsFlow can be collected just once
at kotlinx.coroutines.flow.ChannelAsFlow.markConsumed(Channels.kt:128)
at kotlinx.coroutines.flow.ChannelAsFlow.collect(Channels.kt:153)
at androidx.lifecycle.FlowLiveDataConversions$asLiveData$1.invokeSuspend(FlowLiveData.kt:139)
which leads to the app crash
But if I change to BroadcastChannel, the exception does not raise.
How can I just use the normal Channel as LiveData?
I'm not sure what you are trying to achieve, but you can use receiveAsFlow operator instead of produceAsFlow. Does it help? What is your use-case? Why you need to convert channel to live data?
LiveData is designed to be used with Android components, ie framework elements that are likely to detach and re-attach, thus LiveData and its upstream components will need to handle cancellation in a way that doesn't prevent re-consumption. As @elizarov mentions, receiveAsFlow is the best option here afaik as it will not cancel the "upstream" Channel on Lifecycle death.
@elizarov @ashdavies receiveAsFlow did the job! thanks for pointing this out :)
Most helpful comment
@elizarov @ashdavies
receiveAsFlowdid the job! thanks for pointing this out :)