Android Dagger Hilt:我们是否需要ViewModel的范围注释?

时间:2020-08-09 01:46:12

标签: android dagger android-viewmodel dagger-hilt

在我的应用程序中,我有一个MainActivity,它需要访问ViewModel。我使用DaggerHilt和@ViewModelInject批注注入ViewModel。另外,我在Activity中有两个片段,它们需要访问同一ViewModel才能使用可观察对象将数据彼此传递。

问题: 我发现,只要我的一个片段经过onDestroy(),它的ViewModel就会被杀死。这使我认为Activity和Fragments没有共享同一个ViewModel。

我的问题: 有谁知道我们是否应该在Dagger Hilt中为ViewModel使用范围注释?我没有在Hilt文档或android dev教程/指南中看到这一点。我以为他们在使ViewModels应用程序级别单例,这很有意义。

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

这是我的视图模型代码:

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

1 个答案:

答案 0 :(得分:4)

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

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

如博客文章中所述,如果您希望将一个对象限定在活动范围内并且可以保留配置更改,则可以在任何对象上使用Hilt的@ActivityRetainedScoped并将该对象注入两个片段中。

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

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

使用ViewModel进行范围界定的优势在于,您可以为应用程序中的所有LifecycleOwner对象提供ViewModels。例如,如果您使用Jetpack导航库,则可以在NavGraph上附加ViewModel。

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