https://kotlinlang.org logo
Title
f

Fudge

09/18/2021, 8:21 AM
Hey, any idea why would a
.collect {}
call of a
MutableStateFlow
not work after the initial value? Basically, I create a
MutableStateFlow
in one place and call
emit
(multiple times) there, and at the same time call
.collect {}
in another place, and the callback of
collect
is not executed, except for the initial value. I can clearly see the state of the
Flow
is changing, but
collect
is just not working. I'm also absolutely sure the
collect
call is not getting canceled, as I have tried catching
CancellationException
. The context is a Jetpack Compose app, maybe it's some bug there? SOLVED: the problem was emitting the same list to the StateFlow. Even though the list is changing, its reference has not, and coroutines treat it as the same value, and concludes no new value needs to be emitted. Hence
collect
callback is not called after the initial value.
a

Albert Chang

09/18/2021, 8:33 AM
Is there any reason not to use
mutableStateFlow.value = newValue
instead of
emit()
?
u

uli

09/18/2021, 8:59 AM
Maybe your dispatcher is busy. Hard to guess without any code. Is there any runBlocking involved?
f

Fudge

09/18/2021, 9:16 AM
I want to listen to changes in the StateFlow to update UI accordingly. .collectAsState() doesn't work because.collect{} doesn't work
There is no runBlocking
a

Albert Chang

09/18/2021, 9:18 AM
emit()
is a suspend function and it needs dispatching so there may be some timing issues. That's why I asked you why you are using the suspend function to update the value.
f

Fudge

09/18/2021, 9:44 AM
Ok, i'm gonna try
.value =
Same result
ohhhh I have a guess
Values in state flow are conflated using Any.equals comparison in a similar way to distinctUntilChanged operator. It is used to conflate incoming updates to value in MutableStateFlow and to suppress emission of the values to collectors when new value is equal to the previously emitted one.
so if I have a mutable list that changes, and is being assigned to the StateFlow on every change, since its still referentially equal it wont update
u

uli

09/18/2021, 10:15 AM
True.
f

Fudge

09/18/2021, 10:16 AM
Is there a way to change this behavior to use a different equality?
actually, that won't be needed since in most cases the list won't be referentially equal. In this case I would just copy the list
Yep, it is solved. Thanks for responding
a

Albert Chang

09/18/2021, 10:21 AM
Using
MutableList
as state is suspicious and error-prone. You should always use immutable
List
as state.
f

Fudge

09/18/2021, 10:24 AM
yes i understand that now