如何验证ViewModel作用域绑定是否生效?确认Hilt是否正常工作
ViewModelComponent的作用域是和ViewModel生命周期绑定的——同一个ViewModel实例依赖的对象会保持单例,ViewModel销毁时这些对象也会被回收。你可以通过以下几种方式验证:
给依赖对象加唯一标识,检查同一ViewModel内的实例一致性
给你的虚拟对象添加一个唯一标识(比如UUID)或者计数器,在构造函数初始化:class FakeObject { val instanceId = UUID.randomUUID().toString() // 或者用静态计数器追踪实例数量 companion object { var instanceCount = 0 } init { instanceCount++ } }在ViewModel中注入该对象,然后在Activity中多次获取同一个ViewModel实例的该对象,打印标识:
@HiltViewModel class MyViewModel @Inject constructor( private val fakeObject: FakeObject ) : ViewModel() { fun getFakeObjectId() = fakeObject.instanceId fun getInstanceCount() = FakeObject.instanceCount } // Activity内代码 val firstViewModel: MyViewModel by viewModels() Log.d("HiltScope", "第一次获取的对象ID:${firstViewModel.getFakeObjectId()}") Log.d("HiltScope", "当前实例总数:${firstViewModel.getInstanceCount()}") // 获取同一个ViewModel实例 val secondViewModel: MyViewModel by viewModels() Log.d("HiltScope", "第二次获取的对象ID:${secondViewModel.getFakeObjectId()}")如果两次打印的
instanceId完全相同,说明在同一个ViewModel作用域内,该对象是单例,作用域生效。验证ViewModel销毁后对象会重新创建
当ViewModel被销毁(比如旋转屏幕且Activity未配置android:configChanges,或者App进程被杀死后重启),重新打开Activity获取ViewModel的对象:// 重启后Activity内代码 val newViewModel: MyViewModel by viewModels() Log.d("HiltScope", "重启后对象ID:${newViewModel.getFakeObjectId()}") Log.d("HiltScope", "重启后实例总数:${newViewModel.getInstanceCount()}")此时会打印新的
instanceId,且instanceCount会增加,说明旧ViewModel销毁时依赖对象被回收,新ViewModel创建了新的对象,作用域正确绑定ViewModel生命周期。检查Hilt生成的编译代码
查看项目编译后生成的代码(路径一般为app/build/generated/source/kapt/debug/下的dagger相关包),找到ViewModelComponent的实现类,确认你的provides方法被正确关联到该组件,且没有作用域注解冲突(比如误加了@ActivityScoped之类的其他作用域)。
内容的提问来源于stack exchange,提问作者Anush Parulekar

