Hilt Android 向object类型Module注入字段报错的解决方案
报错原因
dagger does not support injection into kotlin objects的触发逻辑非常明确:Kotlin object 声明的是JVM层面的静态全局单例,实例在类加载时由虚拟机直接生成,Dagger/Hilt 完全无法接管它的实例创建流程,自然没法完成你在APIModule里写的db字段注入,直接抛出不支持错误。
解决方案
推荐方案(Hilt 官方标准写法)
不要在 Module 内部做字段注入,把需要依赖的FirestoreDB直接声明为@Provides方法的入参,Hilt 会自动从依赖图中匹配对应实例传入,不需要你手动维护注入关系。
修正后的APIModule代码:
@Module @InstallIn(SingletonComponent::class) object APIModule { @Singleton @SandalItems @Provides fun provideSandalCustomItems(db: FirestoreDB) = db.getCustomItems("sandals") @Singleton @ShoeItems @Provides fun provideShoeCustomItems(db: FirestoreDB) = db.getCustomItems("shoes") }
注意:我把两个原同名的provide方法改成了不同命名,避免JVM层面出现方法签名重复的编译错误——两个方法参数、返回值完全一致,仅靠注解区分会被JVM识别为重复定义。
你现有的FirestoreDB类不需要任何修改:它被@Singleton标注,实例创建完全由Hilt接管,内部的myAPI字段只要在依赖图中存在对应提供规则,就能正常完成注入。
备选方案(无特殊需求不建议用)
如果你一定要在Module内部持有注入字段,可以把object改为普通class,这种写法下Hilt会实例化Module类完成字段注入,但相比object写法性能稍差,也没有额外收益:
@Module @InstallIn(SingletonComponent::class) class APIModule { @Inject lateinit var db: FirestoreDB @Singleton @SandalItems @Provides fun provideSandalCustomItems() = db.getCustomItems("sandals") @Singleton @ShoeItems @Provides fun provideShoeCustomItems() = db.getCustomItems("shoes") }
开发提示
- 所有
object类型的Dagger/Hilt Module,都不要写@Inject标注的字段,这类Module的定位就是纯依赖提供容器,所有依赖都通过方法参数传入 object类型Module里的@Provides方法可以加上@JvmStatic注解,编译为JVM静态方法,能略微提升注入性能,不影响逻辑正确性- 只要类的实例创建由Hilt接管(比如
@Singleton标注的业务类、Activity/Fragment等Android系统类),就可以正常使用@Inject做字段/构造函数注入,不要在Hilt不接管实例创建的类(比如Kotlin object、手动new的自定义类)里直接用@Inject注入字段。
内容的提问来源于stack exchange,提问作者Firate
相关产品推荐
相关产品推荐

