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..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.htmlshareIn
or stateIn
is more appropriate depends on whether the flow carries events or stateshareIn
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 activechannelFlow
is a good example of when this is usefulrsktash
12/18/2020, 4:00 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 PMcollect
to something like a remote device will establish its own new connection to it, and layer any sort of sharing on top.connect
multiple times?Lilly
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