首页 > 解决方案 > 为什么导航返回后会创建一个新的 ViewModel 实例?

问题描述

我目前正在开发基于MVVM的 Android 应用程序,因此我使用ViewModel原理来包含我的 UI 数据。

我也知道ViewModel链接到它的所有者,并且当所有者被销毁时它被销毁。(https://developer.android.com/topic/libraries/architecture/viewmodel)。

在此处输入图像描述

我的问题发生在片段 A 和 B 之间(在上图中可见)。

我的 Fragment A 包含一个 recyclerview,当我单击该元素时,它会使用组件导航将我定向到 Fragment B(参见下面的示例)。

view?.findNavController()?.navigate(R.id.action_commandListFragment_to_commandDetailsFragment)

我的片段 B 使用 ViewModelProvider 初始化“CommandDetailViewModel”,其子片段(C & D)通过将“requireParentFragment()”作为 ViewModelProvider 的参数传递来检索它。

//Fragment B
mviewModel = ViewModelProvider(this).get(CommandDetailsViewModel::class.java)


//Fragment C & D
mparentViewModel = ViewModelProvider(requireParentFragment()).get(CommandDetailsViewModel::class.java)

如果我单击片段 D 上的按钮,我会返回片段 A,始终使用控制器导航。

//In Fragment B
mviewModel.mCurrentCommandFinished.observe(viewLifecycleOwner, Observer {
        if(it){
            view?.findNavController()?.navigate(R.id.action_commandDetailsFragment_to_commandListFragment)
        }
    })

到目前为止,我明白了,但我意识到我做错了,确实,返回片段 A 这样做是因为 ViewModel 的布尔 LiveData 更改为“true”,因此即使在导航之后也保留为“true”。

当我单击第 1 项时,我预计会遇到问题,变量为 true 我会立即被放回我的列表中,但事实并非如此,创建了一个新的 ViewModel,因此将值设置为 false(默认一)我不明白为什么。

导航是否具有完全破坏片段 B 以及关联的 viewModel 的效果?

因为我不明白为什么每次单击我的元素时都会创建一个新的 viewModel 实例,而我的子片段设法获取先前创建的实例。

注意: viewModel 的影响是在片段 B、C 和 D 中的“onActivityCreated(savedInstanceState: Bundle?)”中完成的。

编辑:我试图在片段 B 的覆盖“onDestroy()”函数中添加一个日志,我发现片段没有被破坏,他的 VM 也没有。

问题是我重新创建了我的片段的一个新实例

view?.findNavController()?.navigate(R.id.action_commandListFragment_to_commandDetailsFragment)

有没有办法检索“原始”实例或销毁它?

编辑2:这是我的错,我没有利用从片段B到片段A的动作中的“popUpTo”和“popUpToInclusive”变量,所以我的片段B仍在堆栈中但不再使用,现在它被正确销毁(https://developer.android.com/guide/navigation/navigation-navigate

标签: androidandroid-fragmentsmvvmviewmodelandroid-lifecycle

解决方案


推荐阅读