Can't get previous emitted values from Flow.
class TestActivity: ComponentActivity() {
...
private val flowA = MutableStateFlow(0)
private val flowB = MutableStateFlow("")
init {
flowB.onEach { Log.d("flowtest", "test - $it") }
.launchIn(lifecycleScope)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
flowB.value = "1"
flowB.value = "2"
flowB.value = "3"
flowA.map { "ignore" }
.onEach {
flowB.value = "4"
flowB.value = "5"
flowB.value = "6"
}
.launchIn(lifecycleScope)
flowA.value = 0
...
}
expect
test - 1
test - 2
test - 3
test - 4
test - 5
test - 6
result
test - 1
test - 2
test - 3
test - 6
What is missing point that concept of Flow?
How can I get previous emitted values?
This is a bit of a guess since I'm not bothering to put together a project and test it.
First, there are two things to remember about StateFlow.
So, looking at your code, at first glance I would expect you to see only:
This is because you're emitting on the main thread and collecting on the main thread, so whenever you have multiple StateFlow value changes in a row, I would expect only the last one called in a method to "stick" since the collector is having to wait its turn for the main thread to be relinquished before it can collect its next value.
So why do
1and2appear?Well, actually,
lifecycleScopedoesn't useDispatchers.Main. It usesDispatchers.Main.immediate, which behaves a little differently. Theimmediateversion runs suspending code immediately in place if you are already on theMainthread, instead of yielding to other coroutines first.So, I'm theorizing that when you change the value on the main thread, but you are collecting
flowB'sonEachonDispatchers.Main.immediate, so it gets a chance to immediately run itsonEachright in place each time you emit a value toflowB.But, a reminder, I haven't actually tested flows with
immediateto test this hypothesis. It's just the only reason I can think of that would explain the behavior. To test this theory yourself, you can change to usinglaunchIn(lifecycleScope + Dispatchers.Main)in both places and see if1and2disappear.