Jetpack Compose中是否有类似rememberSaveable的内存级状态保存API?
在Jetpack Compose中实现内存级跨配置状态的简洁方案
你要找的是跨配置变化(如设备旋转)保留但不持久化到磁盘的状态API,本质就是利用viewModel()的内存持有特性,但想跳过自定义ViewModel类的繁琐步骤,像rememberSaveable那样一行搞定。
核心结论
直接用viewModel()配合mutableStateOf就能实现,无需额外写ViewModel类。viewModel()创建的对象会绑定到宿主(Activity/Fragment)的ViewModelStore,跨配置变化时不会被销毁,且状态仅存于内存,应用退出后自动释放——这完全符合你的需求。
简化实现(一行搞定)
@Composable fun HelloWorld() { // 直接用viewModel持有MutableState,初始化逻辑写在lambda里 val needsToBeInitialized by viewModel<MutableState<Boolean?>> { mutableStateOf(getBooleanOrNullSomehow()) } // 后续直接使用needsToBeInitialized即可 }
自定义简化函数(可选)
如果觉得上面的写法不够直观,可以封装一个自定义Compose函数,让调用方式更接近rememberSaveable:
@Composable inline fun <reified T : Any> rememberViewModelState(initializer: () -> T): T { return viewModel { initializer() } }
使用时就和rememberSaveable几乎一样:
@Composable fun HelloWorld() { val needsToBeInitialized by rememberViewModelState { mutableStateOf(getBooleanOrNullSomehow()) } }
为什么不用remember?
remember只能在重组过程中保留状态,但设备旋转会触发宿主(Activity/Fragment)的销毁重建,此时remember持有的状态会被清除——这正是你需要避免的情况。
优化你现有代码的小建议
如果你坚持用自定义ViewModel类,建议用LaunchedEffect替代手动的initialized标记,避免每次重组都执行检查:
class MyViewModel : ViewModel() { val needsToBeInitialized = mutableStateOf<Boolean?>(null) } @Composable fun HelloWorld() { val model: MyViewModel = viewModel() var needsToBeInitialized by model.needsToBeInitialized // LaunchedEffect(Unit)仅在首次重组时执行一次 LaunchedEffect(Unit) { if (model.needsToBeInitialized.value == null) { model.needsToBeInitialized.value = getBooleanOrNullSomehow() } } }
内容的提问来源于stack exchange,提问作者Szymon Marczak
相关产品推荐
相关产品推荐

