使用Hilt在Worker中注入MyRepository报错,求问题原因
Hilt Worker注入Repository报错排查与解决
问题场景
使用Hilt在Worker类中注入MyRepository,相关代码如下:
MyRepository实现
class MyRepository @Inject constructor( private val myDao: IMyDao ){ ... }
MyModule配置
@InstallIn(SingletonComponent::class) @Module class MyModule { @Provides fun provideMyRepository(MyDao: IMyDao): MyRepository{ return MyRepository(MyDao) } }
Worker中的错误写法
class MyWorker(appContext: Context, workerParams: WorkerParameters) : Worker(appContext, workerParams) { private val myRepository: MyRepository = EntryPointAccessors.fromApplication(appContext, MyRepository::class.java) }
启动Worker时触发异常:
java.lang.ClassCastException: Cannot cast com.freedom.android.DaggerMyApplication_HiltComponents_SingletonC$SingletonCImpl to com.freedom.android.MyRepository
需求:不想为依赖额外定义独立接口,直接注入MyRepository。
错误原因
EntryPointAccessors.fromApplication()的第二个参数必须是Hilt EntryPoint接口的Class对象,你直接传入了MyRepository::class.java。Hilt返回的是内部生成的Singleton组件实例,无法强制转换为MyRepository类型,因此抛出类型转换异常。
解决方法
Hilt的EntryPoint机制确实依赖接口,但可以定义极简的内部接口,无需额外独立文件,完全满足你的需求:
- 在MyWorker内部定义EntryPoint接口并获取依赖:
class MyWorker(appContext: Context, workerParams: WorkerParameters) : Worker(appContext, workerParams) { // 定义内部EntryPoint接口,仅暴露所需依赖 @EntryPoint @InstallIn(SingletonComponent::class) private interface MyWorkerEntryPoint { fun getMyRepository(): MyRepository } private val myRepository: MyRepository init { val entryPoint = EntryPointAccessors.fromApplication( appContext, MyWorkerEntryPoint::class.java ) myRepository = entryPoint.getMyRepository() } }
- 简化MyModule(可选):
MyRepository已用@Inject标注构造函数,Hilt可直接实例化它,无需额外的@Provides方法。MyModule只需保留IMyDao的提供逻辑:
@InstallIn(SingletonComponent::class) @Module class MyModule { @Provides fun provideMyDao(): IMyDao { return MyDaoImpl() // 替换为你的IMyDao具体实现 } }
修改后即可在Worker中正确获取MyRepository实例,且无需额外独立接口文件。
内容的提问来源于stack exchange,提问作者SageJustus
相关产品推荐
相关产品推荐

