4

在我的应用程序中,我有一个需要访问 ViewModel 的 MainActivity。我正在使用 DaggerHilt 和 @ViewModelInject 注释注入 ViewModel。此外,我在 Activity 中有两个 Fragment,它们需要访问同一个 ViewModel 才能使用 observables 相互传递数据。

问题:我发现每当我的一个片段通过onDestroy()它的 ViewModel 时,它就会被杀死。这让我认为 Activity 和 Fragments 没有共享同一个 ViewModel。

我的问题:有谁知道我们是否应该在 Dagger Hilt 中为 ViewModels 使用范围注释?我没有在 Hilt 文档或 android 开发教程/指南中看到这一点。我曾假设他们正在制作 ViewModels 应用级单例,这是有道理的。

如果我们必须为 ViewModels 使用范围注释,有谁知道哪个级别是合适的?

这是我的视图模型代码:

class MainActivityViewModel @ViewModelInject constructor(
    private val repo: Repo,
    private val rxSharedPrefsRepo: RxSharedPrefsRepo,
    private val resourcesRepo: ResourcesRepo,
    @Assisted private val savedStateHandle: SavedStateHandle
) : ViewModel() {
4

1 回答 1

18

根据Android 和 Hilt 博客文章中的范围,使用@ViewModelInject意味着您传递到 ViewModel 的对象的范围是 ViewModel。

然而,ViewModel 的范围取决于您如何获取 ViewModel(ViewModelStore与 ViewModel 关联的内容)——而不是 Hilt 控制的任何内容。如果by viewModels()在 Fragment 中使用,则 ViewModel 的范围为 Fragment。如果您使用by activityViewModels()or by navGraphViewModels(),那么 ViewModel 将分别被限定为活动或导航图。

正如博文中提到的,如果您想要一个作用域为 Activity 并在配置更改后仍然存在的对象,您可以@ActivityRetainedScoped在任何对象上使用 Hilt 并将该对象注入到两个片段中。

博客文章中介绍了您是否应该使用@ActivityRetainedScoped或使用与 Hilt 分开控制范围的 ViewModel:

使用 Hilt 进行范围设置的优势在于,范围类型在 Hilt 组件层次结构中可用,而使用 ViewModel,您必须从 ViewModel 手动访问范围类型。

使用 ViewModel 作用域的优点是您可以为应用程序中的任何 LifecycleOwner 对象拥有 ViewModel。例如,如果您使用 Jetpack Navigation 库,您可以将 ViewModel 附加到您的 NavGraph。

Hilt 提供有限数量的范围。您可能会发现您没有特定用例的范围 - 例如,在使用嵌套片段时。对于这种情况,您可以回退到使用 ViewModel 进行范围界定。

于 2020-08-09T02:35:15.850 回答