无法通过Hilt注入ActivityContext?HomeManager作用域配置问题排查
Hilt注入@ActivityContext报错原因解析
需求背景
- HomeManager是普通Kotlin类,要求其对象及数据在HomeActivity销毁前一直存在
- 注入TestActivity时需获取全新实例(此逻辑当前运行正常)
问题现象
编写Hilt提供HomeManager实例的代码时,出现报错:cannot be provided without an @Provides-annotated method。但将参数中的@ActivityContext替换为@ApplicationContext后,代码可正常运行。
原错误代码
/** * This class is used to provide object implementation which is Activity scoped. */ @InstallIn(ActivityRetainedComponent::class) @Module object InternalObjectModule { @Provides @ActivityRetainedScoped fun provideHomeManager(@ActivityContext context: Context) = HomeManager(context) }
修改后正常的代码片段
(@ApplicationContext context: Context) =
HomeManager实现代码
class HomeManager (private val context: Context) { private var shop: ShopData? = null fun setShop(mShop: ShopData) { shop = mShop } fun getShop(): ShopData? { return shop } fun getContext(): Context { return context } }
问题根源
核心原因是组件作用域与依赖的可访问性不匹配:
- 你的Module被标注为
@InstallIn(ActivityRetainedComponent::class),这个组件的生命周期跨越Activity配置变更,但它只能访问Application级别的依赖,无法获取Activity级别的对象。 @ActivityContext是绑定到ActivityComponent的依赖,只有安装在ActivityComponent中的Module才能直接注入它。ActivityRetainedComponent的依赖池中没有@ActivityContext的提供者,因此Hilt找不到对应实例,抛出缺少@Provides方法的错误。- 换成
@ApplicationContext后能正常运行,是因为ApplicationContext属于Application级别的依赖,ActivityRetainedComponent可以直接访问Application组件提供的所有依赖,能顺利获取到上下文实例。
可选解决方案
如果确实需要给HomeManager传入Activity上下文,同时保留其“HomeActivity销毁前一直存在”的生命周期,可参考两种方式:
- 方式一:将Module的
@InstallIn改为ActivityComponent::class,但这样HomeManager会随Activity销毁而重建,无法保留配置变更后的实例,不符合需求。 - 方式二:继续使用
ActivityRetainedComponent,在HomeActivity的onCreate中手动将Activity上下文传递给HomeManager(比如调用新增的setter方法),但要注意用弱引用包裹Activity上下文,避免因ActivityRetainedComponent持有Activity实例导致内存泄漏。
内容的提问来源于stack exchange,提问作者Ishika Singh
相关产品推荐
相关产品推荐

