为什么在我使用导航组件关闭片段时调用 viewModel 中的 onCleared?

why onCleared in my viewModel is called when I close the fragment using navigation component?

我已经尝试阅读 ,但我想我找不到解决方案。

假设我有 FragmentA 和 Fragment B。我使用此代码移动到片段 B

val nextDestination = AFragmentDirections.actionToB()
findNavController().navigate(nextDestination)

当我从片段 B 返回到片段 A 时,我的片段中的 onDestroy 被调用,然后我的 ViewModel 中的 onCleared 也被调用。

但是当我旋转 phone(配置更改)时,当调用 onDestroy 时,不会调用 onCleared

所以我之前假设,当调用 onDestroy 时,也会调用 onCleared。但事实并非如此。为什么会有这样的不同行为?当配置更改不同于片段导航时?

我很困惑 onCleared 到底是什么时候被调用的

ViewModel 的全部意义在于根据 ViewModel documentation 保存配置更改,因此预计 ViewModel 不会因配置更改而被清除。

但是,每个 ViewModel 都与一个 ViewModelStoreOwner 相关联。这可能是您的 activity 或者它可能是片段。由 ViewModelStoreOwner 来了解它何时因临时更改(例如配置更改)或永久销毁而被销毁。只有在永久销毁中,每个 ViewModel 的 onCleared() 才会被调用。

对于 activity,永久销毁发生在 activity 完成时(即调用 finish()onBackPressed() 的行为导致 finish() 被调用)。

对于片段,永久销毁发生在片段从返回堆栈中弹出时。这就是当您将片段 B 从返回堆栈中弹出并且return 到 Fragment A - Fragment B 从 FragmentManager 中移除,它经过 onDestroy(),它的 ViewModels 被清除。

一旦从返回堆栈中弹出,或者如果它是返回堆栈中唯一的东西,当activity 当您点击系统后退按钮时完成。