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

Hilt依赖注入异常:添加@Provides后仍无法检测依赖

问题解决:Hilt注入UseCase到ViewModel失败的排查与修复

我在实践Clean Architecture时,将应用拆分为App、Data、Domain三个模块,在Data模块中创建了标注@Module和@InstallIn(SingletonComponent::class)的UseCasesModule,App模块已依赖Domain和Data模块。但在ViewModel中注入UseCase时出现错误:

com.example.usecases.GetUserByPersonaNameUseCase cannot be provided without an @Inject constructor or an @Provides-annotated method.

依赖注入路径显示为com.example.dota2stats.di.FactoryModule.providesHomeViewModelFactory(getUserByPersonaNameUseCase)。我有Hilt使用经验,已为提供依赖的方法添加@Provides,给HomeViewModel添加@Inject构造器后仍无效,多次重启应用也未解决,相关代码如下:

依赖提供模块代码

@Module
@InstallIn(SingletonComponent::class)
class UseCasesModule {

    @Singleton
    @Provides
    fun providesGetUserByPersonaNameUseCase(repository: Repository): GetUserByPersonaNameUseCase {
        return GetUserByPersonaNameUseCase(repository)
    }
}

ViewModel代码(已添加@Inject构造器)

class HomeViewModel @Inject constructor(private val getUserByPersonaNameUseCase: GetUserByPersonaNameUseCase) : BaseViewModel() {
    
    override fun handleAction(action: Action): Flow<State> {
        TODO("Not yet implemented")
    }
}

ViewModelFactory代码

class HomeViewModelFactory @Inject constructor(private val getUserByPersonaNameUseCase: GetUserByPersonaNameUseCase) :
    ViewModelProvider.Factory {

    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        return HomeViewModel(getUserByPersonaNameUseCase) as T
    }
}

Activity使用代码

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {

    @Inject
    lateinit var homeViewModelFactory: HomeViewModelFactory
    private lateinit var homeViewModel: HomeViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        homeViewModel = ViewModelProvider(this, homeViewModelFactory)[HomeViewModel::class.java]

    }
}

排查与修复方案

  • 检查UseCase构造器可见性:确保GetUserByPersonaNameUseCase的构造器是public的。如果它在Domain模块中,默认包级私有会导致Hilt无法访问,改成public或者通过模块间可见性设置(比如internal配合跨模块访问配置)让Hilt能获取到。
  • 验证Repository的注入有效性:UseCasesModule中的providesGetUserByPersonaNameUseCase依赖Repository,如果Repository本身没有被Hilt正确提供(缺少@Inject构造器或对应的@Provides方法),会直接导致UseCase无法创建,进而影响ViewModelFactory的注入。
  • 核对FactoryModule配置:错误提示指向FactoryModule.providesHomeViewModelFactory,如果存在该模块,要确认其中的提供方法正确注入了GetUserByPersonaNameUseCase,且模块被@InstallIn到合适的组件(如SingletonComponent或ActivityComponent)。
  • 简化ViewModel注入流程:既然已经给HomeViewModel添加了@Inject构造器,完全可以不用手动写ViewModelFactory,改用@HiltViewModel标注ViewModel,然后在Activity中通过by viewModels()直接获取:
    @HiltViewModel
    class HomeViewModel @Inject constructor(private val getUserByPersonaNameUseCase: GetUserByPersonaNameUseCase) : BaseViewModel() {
        // ...
    }
    
    // Activity中修改为
    private val homeViewModel: HomeViewModel by viewModels()
    
    这种方式更简洁,也能避免手动Factory带来的注入疏漏。
  • 清理缓存并重新编译:Hilt注解处理器生成的代码可能存在缓存问题,执行Clean Project后Rebuild Project,或删除.gradle/caches目录后重新构建,能解决缓存导致的注入异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 17:15:32