You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dagger Hilt报错User cannot be provided without an @Provides-annotated method如何解决

错误原因

  • Hilt组件存在严格的层级可见性限制:ActivityComponent的依赖仅对Activity、Fragment等同生命周期级别的组件可见,ViewModelComponent的父组件仅为SingletonComponent和ActivityRetainedComponent,完全无法访问ActivityComponent中提供的@CurrentUser User实例。
  • 你将RepositoryModule修改为@InstallIn(ActivityComponent::class)后依旧报错,是因为默认ViewModel依赖由ViewModelComponent提供,ActivityComponent的依赖无法反向传递到上层的ViewModelComponent,导致ViewModel找不到对应的ActivityRepository实例。

额外检查:请确认你的@CurrentUser注解本身已添加@Qualifier注解,示例定义如下:

@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class CurrentUser

若未添加@Qualifier,即使依赖层级正确也会抛出找不到提供方法的错误。

解决方法

方案1:将CurrentUser提供升级到ActivityRetainedComponent(推荐)

ActivityRetainedComponent的生命周期和ViewModel完全对齐,同时是ViewModelComponent的父组件,两处都可以正常访问依赖,修改你的User提供模块即可:

@InstallIn(ActivityRetainedComponent::class)
@Module
object MainActivityModule {

    /**
        Provides current user that is stored in an intent after Logged In
    **/
    @Provides
    @CurrentUser
    fun providesCurrentUser(
        @ActivityContext activity: Context
    ): User {
        val intent: Intent = (activity as MainActivity).intent
        return intent.getSerializableExtra(CURRENT_USER) as User
    }
}

你的RepositoryModule保持@InstallIn(ViewModelComponent::class)不变即可正常编译。

方案2:将依赖层级统一为Activity级别

如果你的业务逻辑只需要在Activity生命周期内使用Repository,可以将Repository标记为@ActivityScoped,并在Activity中注入Repository后手动传递给ViewModel,不过该方式代码侵入性较高,不符合Hilt最佳实践。

方案3:全局存储登录态放到SingletonComponent

如果CurrentUser是登录后全局通用的用户信息,不需要依赖Activity的Intent传递,可以将用户信息存储到全局缓存/SP中,将@CurrentUser User的提供模块放到SingletonComponent,整个应用所有级别的组件都可以访问该依赖。

内容的提问来源于stack exchange,提问作者Erjon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 13:24:02