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