在我的应用程序中,我有一个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() {
答案 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进行范围界定。