Arjan van Wieringen
12/09/2022, 6:27 PMhfhbd
12/09/2022, 6:32 PMrememberCoroutineScope
getting canceled when the composable is removed: https://developer.android.com/jetpack/compose/side-effects#remembercoroutinescopeArjan van Wieringen
12/09/2022, 6:36 PMhfhbd
12/09/2022, 7:06 PMrememberCoroutineScope
? For testing you should provide a scope parameter.Casey Brooks
12/09/2022, 7:12 PMrememberCoroutineScope
or other values like that within the DI graph itself, but it’s usually pretty well supported to pass those values into the DI framework at the point when you would get an instance of an objectMichael Paus
12/09/2022, 7:42 PM@Composable
fun DetailsScreen(talkId: String, onNavSelection: (target: ScreenSelector) -> Unit, onBackSelection: (() -> Unit)?) {
val coroutineScope = rememberCoroutineScope()
val viewModel = remember { DetailsScreenViewModel(coroutineScope, talkId) }
DisposableEffect(true) { onDispose { viewModel.dispose() } }
val detailsScreenState by viewModel.detailsScreenState.collectAsState()
...
}
I normally use Koin too but at this point I think that a normal constructor is just good enough. The view model takes an additional parameter talkId
here which configures the specific view model instance. The view model then provides its state via a StateFlow which I import in the view via collectAsState
. I am wondering though whether the dispose
couldn’t be handled completely inside the view model based on the cancelling of the coroutine scope.Casey Brooks
12/09/2022, 7:45 PMcoroutineScope
, which gets cancelled automatically do I don’t need the DisposableEffect
. Heres and example of the library I maintain and use for all my MPP ViewModels, doing this same pattern that Michael postedMichael Paus
12/09/2022, 7:48 PMCasey Brooks
12/09/2022, 7:51 PMcallbackFlow { awaitClose { } }
. The Ballast library helps with observing flows and making sure everything’s done on the coroutineScope properlyCasey Brooks
12/09/2022, 7:54 PMcoroutineContext.job.invokeOnCompletion { }
for use-cases that aren’t using FlowsMichael Paus
12/09/2022, 7:55 PMCasey Brooks
12/09/2022, 7:57 PMdispose()
method.Arjan van Wieringen
12/09/2022, 9:26 PMCasey Brooks
12/09/2022, 9:33 PMviewModelScope
and lifecycle part of the ViewModel class on Android is only necessary on Android. Desktop apps cannot use Android dependencies, but they also do not have the same kind of lifecycle issues that Android apps have. Furthermore, the viewModelScope
is created by the Android framework and isn’t related to the UI, so those viewModels use a different “lifecycle” than the Composable functions they’re created in.
For desktop apps, a normal class with a coroutineScope passed in to its constructor from rememberCoroutineScope()
is the correct alternative. Here’s an example of the same basic idea being done with manual DI in a desktop app. If using Koin or Kodein, the only thing that changes is replacing the ComposeDesktopInjector
with your Koin or Kodein instanceArjan van Wieringen
12/09/2022, 9:35 PMAlexander Maryanovsky
12/11/2022, 12:15 PM