谷歌建议使用SharedViewModel在Fragment之间进行通信,并将其作用域限定为活动。
在单个Activity应用程序中,这意味着Activity将充斥着可能不再需要的ViewModel,并且它们将在整个生命周期内保留。考虑一个扩展注册流程或涉及几个屏幕的示例。
一种推荐的方法是使用父Fragment作为作用域,但如果没有父Fragment,则只能使用不同的Fragment。
我想出了以下解决方案,想知道它有多可行或有多糟糕,是否有更好的解决方法?
假设我有两个名为ExampleOneFragment
和ExampleTwoFragment
的Fragment,为简单起见,我希望它们具有共享作用域,而不实际将其作用域限定为活动。比如说,我想从ExampleTwoFragment更新ExampleOneFragment中的文本视图,因此我为两者创建了一个SharedViewModel,如下所示:
对于ExampleOneFragment
,它将是:
private val mSharedViewModel by lazy {
ViewModelProvider(this).get(SharedViewModel::class.java)
}
对于ExampleTwoFragment
,我想出了以下内容:
private val mSharedViewModel by lazy {
ViewModelProvider(supportFragmentManager().findFragmentByTag(ExampleOneFragment.TAG) ?: this).get(SharedViewModel::class.java)
}
这似乎是有效的,但我不知道可能会引起什么问题。
我发现了另一些解决方案: 根据@mikhehc 在这里,实际上我们可以创建自己的 ViewModelStore。这将允许我们对 ViewModel 存在的范围进行精细控制。但我不知道如何让它适用于 Fragment?
其次,是通过使用相同的键并使用虚拟viewmodel 清除活动范围内的ViewModel的hacky方法,我在这里找到了
有人能指导我正确的方法吗?我不能切换到NavGraphs,因为这已经是一个正在运行的项目,而范围限定到活动范围内感觉就不对。谢谢。
onCleared()
的调用。这个调用会清除我的范围和与之相关联的所有协程。尽管通过dagger
注入的ViewModel
被标记为@Singleton
。我希望通过你的问题进一步了解这种行为。 - Gleichmut