androidandroid-jetpack-composeviewmodel

What's the difference between "viewModel: MyViewModel = viewModel()" and "viewModel: MyViewModel = MyViewModel()" in Android Composable


Here my composable

@Composable
fun CounterScreen(viewModel: MyViewModel = viewModel()) {
    val uiState by viewModel.uiState.collectAsState()

    Column(
        modifier = Modifier.fillMaxSize(),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Text(text = "Counter: ${uiState.count}")
        Spacer(modifier = Modifier.height(16.dp))
        FloatingActionButton(
            onClick = {
                viewModel.increment()
            },
        ) {
            Icon(imageVector = Icons.Default.Add, contentDescription = "Increment")
        }
    }
}

Why the state is preserved with recomposition when I wrote fun CounterScreen(viewModel: MyViewModel = viewModel()) but not with fun CounterScreen(viewModel: MyViewModel = MyViewModel()). However they both create a new instance of MyViewModel. Does someone can explain me? Thanks


Solution

  • With MyViewModel() you always create a new instance.

    The viewModel() function, on the other hand, uses a view model factory behind the scenes to obtain an instance. And that factory provides the same instance for the same ViewModelStoreOwner. The latter defaults to LocalViewModelStoreOwner.current.

    Until that changes, you will always get the same instance. From the documentation:

    Returns an existing ViewModel or creates a new one in the given owner (usually, a fragment or an activity), defaulting to the owner provided by LocalViewModelStoreOwner.

    The created ViewModel is associated with the given viewModelStoreOwner and will be retained as long as the owner is alive (e. g. if it is an activity, until it is finished or process is killed).