Ryan Payne
04/11/2026, 7:34 PMvar isChecked by rememberSaveable { mutableStateOf(false) } <<< does not persist after process death
In a vanilla view model without Molecule, I would:
1. Inject SavedStateHandle into the view model
2. Call getStateFlow()
3. Mutate the key on SavedStateHandle
@HiltViewModel
class DashboardViewModel @Inject constructor(
private val savedStateHandle: SavedStateHandle
) : ViewModel() {
val isChecked by savedStateHandle.getStateFlow("is_checked", false)
}saket
04/11/2026, 9:09 PMLocalSaveableStateRegistry manually at the place where you launch moleculeRyan Payne
04/11/2026, 11:41 PMZac Sweers
04/12/2026, 5:13 AMsaket
04/12/2026, 5:41 AMRyan Payne
04/12/2026, 4:25 PMRyan Payne
04/13/2026, 11:53 PMsaket
04/14/2026, 12:08 AMRyan Payne
05/31/2026, 4:23 PMproduceState function from my vm.
@HiltViewModel
class DashboardViewModel @Inject constructor(
private val savedStateHandle: SavedStateHandle
) : ViewModel() {
@Composable
override fun produceState(): DashboardUiState {
var isChecked by rememberSaveable { mutableStateOf(false) }
return DashboardUiState(
isChecked = isChecked,
)
}
}
Since produceState is called in a Compose ui context, state persists after process death.
@Composable
fun DashboardScreen(
viewModel: DashboardViewModel
) {
val uiState = viewModel.produceState()
// ...
}
For tests, I use Molecule to convert the produceState function into a Flow.
moleculeFlow(RecompositionMode.Immediate) {
withCompositionLocal(
LocalLifecycleOwner provides TestLifecycleOwner().apply {
handleLifecycleEvent(Lifecycle.Event.ON_START)
},
) {
viewModel.produceState()
}
}.test {
awaitItem()
// More assertions...
}
Credit goes to @eygraber for coming up with this approach and sharing it with me. :)Stylianos Gakis
05/31/2026, 6:57 PMZac Sweers
05/31/2026, 7:04 PMZac Sweers
05/31/2026, 7:06 PMeygraber
05/31/2026, 7:20 PMconfigChanges avoids 99.9% of the cases where retention would come into play (maybe it's been the various domains I've been working in, but I haven't found wallpaper changes to be particularly common), I've found save state (particularly via rememberSaveable) covers almost all cases. I have been meaning to look at utilizing the retain APIs as an optimization when needed though.eygraber
05/31/2026, 7:21 PMZac Sweers
05/31/2026, 7:21 PMeygraber
05/31/2026, 7:23 PMStylianos Gakis
05/31/2026, 11:44 PMeygraber
06/01/2026, 2:03 AMRyan Payne
06/02/2026, 12:24 AM