'How to launch lifecycle.whenResumed coroutine immediately so flow-collection starts before returning?
I listen to a flow in whenResumed, so events are only collected while app is resumed. However I would like to ensure that I have started listeners before I run code that might send events that must be collected.
init {
lifecycleScope.launchWhenResumed {
stateUpdates.collect { onUpdate(it) }
}
// Now do stuff that might trigger event, which I want to collect above.
// This does not have to be in init {}, an initialize() is fine
doMyThing()
}
I know I can use a sharedFlow with a cache, but for my usage-case, a cache might be problematic.
--
I know I can do the following, where line 1 is executed immediately, but here again line 2 is dispatched and thus executed later:
CoroutineScope(Dispatchers.Main).launch(start = CoroutineStart.UNDISPATCHED) {
// 1
lifecycle.whenResumed {
// 2
}
}
==== Update 3. March 2022
Thanks IR42 for good info on option. What I was actually after is scheduling many different types of collectors, and then do my thing.
init {
lifecycleScope.launchWhenResumed {
launch { stateUpdates1.collect { onUpdate1(it) } }
launch { stateUpdates2.collect { onUpdate2(it) } }
launch { stateUpdates3.collect { onUpdate3(it) } }
launch { stateUpdates4.collect { onUpdate4(it) } }
launch { stateUpdates5.collect { onUpdate5(it) } }
}
// Now do stuff that might trigger event, which I want to collect above.
// This does not have to be in init {}, an initialize() is fine
doMyThing()
}
I would like a nice idiomatic way of doing this. I don't see how to do that with onSubscription(), though I appreciate the input as it was new to me.
Solution 1:[1]
You can use onSubscription
lifecycleScope.launchWhenResumed {
stateUpdates
.onSubscription {
// Do my thing, that might result in state-update
}
.collect { onUpdate(it) }
}
Solution 2:[2]
Instead of doing this:
runBlocking {
lifecycleScope.launchWhenResumed {
stateUpdates.collect { onUpdate(it) }
}
yield()
}
Do this, which is less fragile:
lifecycleScope.launchWhenResumed {
yield()
stateUpdates.collect { onUpdate(it) }
}
It's still a bit fragile, though, because it relies on the order coroutines were submitted.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Tenfour04 |
