KamilH
01/09/2020, 9:57 AMFlow wrapper around LiveData and I have a problem, because it closes (invokeOnClose is called) immediately after first value is emitted by Observer.
fun <T> LiveData<T>.asFlow(): Flow<T> = channelFlow {
value?.let { offer(it) }
val observer = Observer<T> { t -> t?.let(this::offer) }
observeForever(observer)
invokeOnClose {
removeObserver(observer)
}
}
To be sure my CoroutineScope is not causing this cancellation, I run this also in GlobalScope and the behaviour was the same.
How can I see what is causing cancellation? I analysed stack trace, but I didn’t see anything interesting there.KamilH
01/09/2020, 12:43 PMLiveData implementation, it have addObserver function which is not available in Android’s LiveData even though it can be replaced with observeForever.
What is interesting, I looked at this code again and decided to give a try to awaitClose function and it seems to work as expected - Channel is not closed immediately. When I’m using invokeOnClose, then Channel is closed. Can anyone explain why it acts like that?
To conclude, when I changed function body to this one:
fun <T> LiveData<T>.asFlow(): Flow<T> = channelFlow {
value?.let { offer(it) }
val observer = Observer<T> { t -> t?.let(this::offer) }
observeForever(observer)
awaitClose {
removeObserver(observer)
}
}
I get expected behavior, so channel is not closed immediately and it’s offering events from LiveData.Dominaezzz
01/09/2020, 1:33 PMawaitClose waits for the channel to be closed before returning.KamilH
01/09/2020, 5:49 PMinvokeOnClose it’s effectively closes the Channel (and executes lambda) while awaitClose not? I thought both of them should just be called when “something” called close on the ChannelDominaezzz
01/09/2020, 5:56 PMinvokeOnClose does what it says and what you expect. It's just that after you call invokeOnClose, the code in the channelFlow lambda is done and once that happens channelFlow closes the channel, which then calls invokeOnClose .....
awaitOnClose happens to also suspend the channelFlow lambda until the channel is closed in some other way.KamilH
01/09/2020, 6:24 PM