我有一个Activity应用程序。在应用程序的一部分中,存在片段的主从组合,这些片段使用a shared ViewModel在它们之间共享一些数据。我面临的问题是,即使两个Fragment都已销毁,也不会调用ViewModel的onCleared()方法。仅当活动被销毁时才调用onCleared()。
这应该如何工作?因为在单个Activity模型中这是没有用的,因为Activity始终是活动的。还是我错过了什么?
答案 0 :(得分:1)
如果您在ViewModelProviders.of(this)
中传递了该活动,那么可以,那就是预期的行为。要使ViewModel仅限于主片段和局部片段,您可能需要为其创建父片段,例如MasterDetailFragment
,该片段同时包含MasterFragment
和DetailsFragment
答案 1 :(得分:1)
要给出可靠的答案而又不花一点点代码就会有些困难。我的第一个猜测是,您可能将ViewModel
的范围定为Activity
,而不是Fragment
的范围。
//inside of fragment onCreate()
//scoped to fragment
viewModel = ViewModelProviders.of(this).get(SharedViewModel::class.java)
//scoped to activity
viewModel = ViewModelProviders.of(requireActivity()).get(SharedViewModel::class.java)
在这种情况下,请查看图表中ViewModel
的范围。那么onCleared()
从未被调用的原因是,您的Activity
从未在技术上遭到破坏,因为它使您的应用程序处于前台。
如果这不是您问题的正确解决方案,那么我认为ViewModel
上的文档可能是开始寻找正确答案的好地方。编码愉快!
答案 2 :(得分:0)
原始问题中a shared ViewModel的链接已更新,但此处的答案未更新。因此,这是基于安德鲁·斯坦梅茨的答案的最新答案。
下面是从Google文档中创建共享的ViewModel
的方法:
private val model: SharedViewModel by activityViewModels()
由于正在使用activityViewModels
,ViewModel
将具有活动范围。首次使用后,它将存储在其父活动的viewModelStore
中,活动结束时将调用ViewModel的onCleared()
。
如果ViewModel
的创建如下,
private val model: SharedViewModel by viewModels()
ViewModel
仅将范围作为其片段,因为它存储在其片段自己的viewModelStore
中,它可以在配置更改(例如屏幕旋转)期间幸存下来,但是当所有片段都使用时完成了。它也会被摧毁。