【问题标题】:Android Dagger Hilt: Do we need scope annotations for ViewModels?Android Dagger Hilt:我们需要 ViewModel 的范围注释吗?
【发布时间】:2020-08-09 01:46:12
【问题描述】:

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

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

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

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

这是我的视图模型代码:

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

【问题讨论】:

    标签: android dagger android-viewmodel dagger-hilt


    【解决方案1】:

    根据Scoping in Android and Hilt blog post,使用@ViewModelInject 意味着您传递到 ViewModel 的对象的作用域是 ViewModel。

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

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

    您应该使用@ActivityRetainedScoped 还是使用与 Hilt 分开控制范围的 ViewModel 在博文中进行了介绍:

    使用 Hilt 作用域的优势在于,作用域类型在 Hilt 组件层次结构中可用,而使用 ViewModel,您必须从 ViewModel 手动访问作用域类型。

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

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

    【讨论】:

    • 我明白了,我误解了我的问题所在。我的两个子片段都调用了by viewModels(),这意味着它们的范围仅限于片段。使用by activityViewModels() 为我修复了它。非常感谢您的帮助!
    • 请注意,您也可以使用by viewmodels ({requireParentFragment()}) 将 ViewModel 限定为父片段。如果您的父片段没有作为活动一直存在,那将很重要。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多