【发布时间】:2019-05-08 06:05:09
【问题描述】:
编辑:这个问题有点过时了,因为 Google 已经让我们能够将ViewModel 范围限定为导航图。更好的方法(而不是试图清除活动范围的模型)是为适当数量的屏幕创建特定的导航图,并针对这些屏幕创建范围。
参考android.arch.lifecycle.ViewModel 类。
ViewModel 的范围是与其相关的 UI 组件的生命周期,因此在基于 Fragment 的应用程序中,这将是片段生命周期。这是一件好事。
在某些情况下,人们希望在多个片段之间共享一个ViewModel 实例。具体来说,我对许多屏幕与相同的基础数据相关的情况感兴趣。
(当多个相关片段显示在同一屏幕上但this can be worked around by using a single host fragment as per answer below时,文档建议类似的方法。)
这在official ViewModel documentation中讨论:
ViewModel 也可以用作不同的通信层 活动的片段。每个 Fragment 都可以获取 ViewModel 通过他们的活动使用相同的密钥。这允许通信 以解耦的方式在片段之间进行,这样它们就不需要 直接与另一个 Fragment 对话。
换句话说,要在代表不同屏幕的片段之间共享信息,ViewModel 的范围应限定为 Activity 生命周期(根据 Android 文档,这也可以用于其他共享实例)。
现在在新的 Jetpack 导航模式中,建议使用“一个 Activity / 许多片段”架构。这意味着活动在应用程序被使用的整个过程中都存在。
即范围为Activity 生命周期的任何共享ViewModel 实例将永远不会被清除 - 内存保持持续使用状态。
为了在任何时候保留内存并尽可能少地使用,如果不再需要时能够清除共享的ViewModel 实例,那就太好了。
如何从ViewModelStore 或持有者片段中手动清除ViewModel?
【问题讨论】:
-
嘿!如何创建您自己的保留片段并将您的视图模型限定为该保留片段?现在,您可以完全控制视图模型的生命周期。如果需要,您只需要使活动添加或删除片段,并通过活动将保留的片段和其他片段连接在一起。听起来确实像是在写一些样板代码,但我想知道你的想法。
-
我不知道是否可以使用 getTargetFragment() 作为范围:
ViewModelProvider(requireNotNull(targetFragment)).get(MyViewModel::class.java) -
是的,有办法,我已经解释过了here
-
对于尝试实施更新解决方案的人,请转到此处medium.com/androiddevelopers/…
标签: android android-architecture-components android-jetpack android-viewmodel