Slackbot
11/19/2020, 8:36 PMJohn O'Reilly
11/19/2020, 8:37 PMLiveData.observe()
automatically unregisters the consumer when the view goes to the STOPPED
state, whereas collecting from a StateFlow
or any other flow does not.Timo Drick
11/19/2020, 8:39 PMJohn O'Reilly
11/19/2020, 8:41 PMTimo Drick
11/19/2020, 8:42 PMJohn O'Reilly
11/19/2020, 8:42 PMLeland Richardson [G]
11/19/2020, 8:42 PMJohn O'Reilly
11/19/2020, 8:43 PMonStop()
John O'Reilly
11/19/2020, 8:44 PMLeland Richardson [G]
11/19/2020, 8:44 PMLeland Richardson [G]
11/19/2020, 8:44 PMlouiscad
11/19/2020, 8:46 PMflatMapLatest
operator on the Lifecycle.isStartedFlow()
and bring your flow when started, and emptyFlow()
otherwise.
The Lifecycle.isStartedFlow()
I'm referring to is documented and available here:
https://github.com/LouisCAD/Splitties/tree/main/modules/lifecycle-coroutinesLeland Richardson [G]
11/19/2020, 8:49 PMLeland Richardson [G]
11/19/2020, 8:49 PMLeland Richardson [G]
11/19/2020, 8:50 PMLeland Richardson [G]
11/19/2020, 8:50 PMJohn O'Reilly
11/19/2020, 8:50 PMTimo Drick
11/19/2020, 8:51 PMLeland Richardson [G]
11/19/2020, 8:52 PMLeland Richardson [G]
11/19/2020, 8:52 PMLeland Richardson [G]
11/19/2020, 8:52 PMJohn O'Reilly
11/19/2020, 8:52 PMLeland Richardson [G]
11/19/2020, 8:52 PMJohn O'Reilly
11/19/2020, 8:53 PMLeland Richardson [G]
11/19/2020, 8:54 PMLeland Richardson [G]
11/19/2020, 8:54 PMLeland Richardson [G]
11/19/2020, 8:57 PMLeland Richardson [G]
11/19/2020, 8:58 PMIan Lake
11/19/2020, 9:22 PMJohn O'Reilly
11/19/2020, 9:44 PMJohn O'Reilly
11/19/2020, 9:45 PMJohn O'Reilly
11/20/2020, 11:21 PMcollectAsState()
can be passed a CoroutineContext
...wondering if that could perhaps be used to influence behaviour in this scenarioIan Lake
11/20/2020, 11:31 PM.stateIn(viewModelScope, SharingStarted.Eagerly, emptyList())
, you'll always be collecting on the upstream flow as long as the ViewModel
exists, no matter what state / how many collectors you have downstream from that - whether you're stopped, started, in the background, etc. won't matterIan Lake
11/20/2020, 11:33 PMSharingStarted.WhileSubscribed
if you want your upstream collecting to be cancelled when your subscribers go away: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-sharing-started/-while-subscribed.htmlIan Lake
11/20/2020, 11:34 PMJohn O'Reilly
11/20/2020, 11:36 PMstateIn
but didn't pay enough attention to that param!John O'Reilly
11/21/2020, 9:13 AMJohn O'Reilly
11/24/2020, 11:38 AMViewModel
John O'Reilly
11/28/2020, 4:20 PMlouiscad
11/28/2020, 4:29 PMimport androidx.lifecycle.Lifecycle
import kotlinx.coroutines.flow.*
import splitties.lifecycle.coroutines.isStartedFlow
fun <T> Flow<T>.whileStarted(lifecycle: Lifecycle): Flow<T> {
return lifecycle.isStartedFlow().flatMapLatest { isStarted ->
if (isStarted) this else emptyFlow()
}
}
With that, you can then at use site simply do this:
someFlow.whileStarted(lifecycle).collectAsState()
You can even go one step further and make an extension named collectAsStateWhileStarted(lifecycle)
.
I find this neater and more scalable than tangling your composable code with the activity bound onStart
and onStop
where you keep the Job
in a var
. What do you think?louiscad
11/28/2020, 4:32 PMcollectAsStateWhileStarted
@Composable
function might not even need the Lifecycle
parameter if it can be retrieved via the ambients.John O'Reilly
11/28/2020, 4:32 PMlouiscad
11/28/2020, 4:34 PMisStartedFlow
function fits in a small file with only dependencies to kotlinx.coroutines and AndroidX Lifecycle.John O'Reilly
11/28/2020, 4:34 PMlouiscad
11/28/2020, 4:35 PMJohn O'Reilly
11/28/2020, 4:36 PMlouiscad
11/28/2020, 4:38 PM