Lilly
12/18/2020, 3:00 PMAdam Powell
12/18/2020, 3:49 PMmyViewModel.viewModelScope
? Collecting a flow in a composable function will have a much narrower scope, it will start collecting when that composable enters the composition and stop collecting when it leaves. `viewModelScope`s live much longer and will leave the flow collecting and potentially performing work when nothing needs it.Adam Powell
12/18/2020, 3:51 PM.shareIn
flow operator lets you specify a timeout; you can shareIn
your viewModelScope
and use such a timeout to keep unnecessary work to a minimum: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-sharing-started/-while-subscribed.htmlAdam Powell
12/18/2020, 3:52 PMshareIn
or stateIn
is more appropriate depends on whether the flow carries events or stateAdam Powell
12/18/2020, 3:53 PMshareIn
or stateIn
, then you can collect the resulting shared/stateflow in your composable but there will be only one underlying collect on the upstream flow while one or more subscribers (i.e. composables listening to the flow) are activeAdam Powell
12/18/2020, 3:55 PMchannelFlow
is a good example of when this is usefulrsktash
12/18/2020, 4:00 PMrsktash
12/18/2020, 4:02 PMAdam Powell
12/18/2020, 4:10 PMLilly
12/18/2020, 4:10 PMby, "in view model" you mean using myViewModel.viewModelScope ?
yes, to be more concrete I mean doing sth. like this:
private val _state: MutableStateFlow<ConnectBluetoothDeviceUseCase.BluetoothConnectState> =
MutableStateFlow(
ConnectBluetoothDeviceUseCase.BluetoothConnectState.Loading
)
fun connect(device: BluetoothDevice) {
viewModelScope.launch {
connectBluetoothDevicesUseCase.connect(device).collect { connectState ->
_state.value = connectState
}
}
}
@rsktash We have the same intention.
@Adam Powell I was wondering if I should avoid collecting the state that comes from my ConnectionUseCase
then updating the StateFlow
in favor of collecting it directly in composable. Would it be a better solution?Adam Powell
12/18/2020, 4:12 PMAdam Powell
12/18/2020, 4:15 PMAdam Powell
12/18/2020, 4:17 PMcollect
to something like a remote device will establish its own new connection to it, and layer any sort of sharing on top.Adam Powell
12/18/2020, 4:17 PMconnect
multiple times?Adam Powell
12/18/2020, 4:18 PMLilly
12/18/2020, 4:19 PMrsktash
12/18/2020, 4:22 PMAdam Powell
12/18/2020, 4:24 PMLilly
12/18/2020, 4:27 PMAdam Powell
12/18/2020, 4:29 PMmutableStateOf
instead, if the primary consumer of that information is your compose uirsktash
12/18/2020, 4:33 PMLilly
12/18/2020, 4:33 PMmutableStateOf
and StateFlow
. They both have the same behavior not? -> to notify ui on changesAdam Powell
12/18/2020, 4:36 PMprivate val _foo = MutableStateFlow<Type>(...)
val foo: StateFlow<Type> get() = _foo
thing and you're just setting _foo.value = newValue
as things happen, that translates pretty directly to
var foo by mutableStateOf<Type>(...)
private set
and is generally nicer to work with. And if some other code outside of a composable function wants to observe changes to it, it can use snapshotFlow { myObject.foo }
and collect that. Composable functions can just refer to foo
directly and the change observation happens automatically.Lilly
12/18/2020, 4:40 PM