从 compose 中的导航返回时会重新创建 ViewModel

问题描述 投票:0回答:1

我正在重构原始项目 xml -> compose,并遇到了一些问题。 当我导航

A -> B and Back to A
时,A 的视图模型被重新创建。 我期望的是遵循原始生命周期(onDestroyed,而不是 onDispose)。 我已经知道如何在compose中实现lifeCycleObserver,但不了解compose中viewmodel的lifeCycle。 我想在生命周期中使用 Compose 的视图模型,就像片段的视图模型一样,而不是在重组时重新创建。 这种思维在撰写中是反模式吗?那么,如何保持viewModel的生命周期呢?

我不想将视图模型作为参数传递,因为我有一个针对同一撰写屏幕的嵌套导航。并且不要使用相同的lifecycleOwner(MainActivity的lifeCyclerOwner)

android-jetpack-compose
1个回答
0
投票

我不知道您的具体情况,因为它没有在问题中声明,但我假设您的意思是在返回时再次触发

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 已重新组合(例如返回时)。

© www.soinside.com 2019 - 2024. All rights reserved.