我正在重构原始项目 xml -> compose,并遇到了一些问题。 当我导航
A -> B and Back to A
时,A 的视图模型被重新创建。
我期望的是遵循原始生命周期(onDestroyed,而不是 onDispose)。
我已经知道如何在compose中实现lifeCycleObserver,但不了解compose中viewmodel的lifeCycle。
我想在生命周期中使用 Compose 的视图模型,就像片段的视图模型一样,而不是在重组时重新创建。
这种思维在撰写中是反模式吗?那么,如何保持viewModel的生命周期呢?
我不想将视图模型作为参数传递,因为我有一个针对同一撰写屏幕的嵌套导航。并且不要使用相同的lifecycleOwner(MainActivity的lifeCyclerOwner)
我不知道您的具体情况,因为它没有在问题中声明,但我假设您的意思是在返回时再次触发
ViewModel
中的某些操作。
因为
ViewModel
生命周期与可组合项或导航生命周期无关。我认为问题在于您直接在可组合函数本身中执行一些操作。返回时,这部分会再次触发,即使它位于像 LaunchedEffect
这样的副作用处理程序中。
因此,如果您在 ViewModel 的 init 块内添加一条日志语句,并在可组合代码触发的函数内添加另一个日志语句,您将看到 init 块内的日志仅被触发一次。但是,返回时会再次调用函数的日志(即使它位于
LaunchedEffect
内)。
示例:
- ViewModel
class ProfileViewModel: ViewModel() {
init {
Log.d(TAG, "Statue: Coming from init block")
}
fun getUserProfile() {
Log.d(TAG, "Statue: Coming from getUserProfile function")
}
}
- 撰写屏幕
@Composable
fun ProfileScreen(viewModel: ProfileViewModel) {
LaunchedEffect(Unit) {
viewModel.getUserProfile()
}
// Your composables
}
此处,ViewModel 作为参数传递,您可以在设置导航时使用 Hilt 或 Koin 等 DI 框架注入它。
- 结果:
init块中的日志消息只会被触发一次,因为 ViewModel 实例未附加到可组合生命周期并且 只会创建一次。
每次都会创建来自 getUserProfile 函数的日志消息 ProfileScreen 已重新组合(例如返回时)。