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