Android Hilt多模块引用Core模块时出现注入循环错误求助
模块结构与依赖关系
- App模块依赖Api和Core模块
- Api模块依赖Core模块
Core模块中的VersionProvider实现
class VersionProvider @Inject constructor(@ApplicationContext context: Context) { val versionName = context.packageManager.getPackageInfo(context.packageName, 0).versionName val versionCode = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { context.packageManager.getPackageInfo(context.packageName, 0).longVersionCode } else { @Suppress("DEPRECATION") context.packageManager.getPackageInfo(context.packageName, 0).versionCode } }
这个类在Api和App模块的多个类中被注入使用。
Core模块的Hilt模块配置
@Module @InstallIn(SingletonComponent::class) abstract class CoreModule { @Singleton @Binds abstract fun bindVersionProvider( provider: VersionProvider ): VersionProvider }
编译时出现的依赖循环错误
C:\Code\xxx\app\build\generated\hilt\component_sources\development\com\xxx\App_HiltComponents.java:200:
error: [Dagger/DependencyCycle] Found a dependency cycle: public
abstract static class SingletonC implements App_GeneratedInjector,
^
com.xxx.core.VersionProvider is injected at
com.xxx.core.hilt.CoreModule.bindVersionProvider(provider)
com.xxx.core.VersionProvider is injected at
com.xxx.core.hilt.CoreModule.bindVersionProvider(provider)
...
The cycle is requested via:
com.xxx.core.VersionProvider is injected at
com.xxx.api.core.hilt.ApiClientModule.bindNetworkManager(�, versionProvider)
com.xxx.api.services.helpers.INetworkManager is injected at
com.xxx.api.core.hilt.ApiClientModule.bindInventoryApi(networkManager)
com.xxx.api.services.inventory.InventoryApi is injected at
com.xxx.api.services.inventory.InventoryService(api, �)
com.xxx.api.services.inventory.InventoryService is injected at
com.xxx.api.core.hilt.ServiceModule.bindInventoryService(service)
com.xxx.api.services.inventory.IInventoryService is injected at
com.xxx.managers.inventory.InventoryManager(inventoryService, �)
com.xxx.managers.inventory.InventoryManager is injected at
com.xxx.core.hilt.ManagerModule.bindInventoryManager(manager)
com.xxx.managers.inventory.IInventoryManager is injected at
com.xxx.App.inventoryManager
com.xxx.App is injected at
com.xxx.App_GeneratedInjector.injectApp(com.xxx.App) The following other entry points also depend on it:
dagger.hilt.android.internal.lifecycle.HiltViewModelFactory.ViewModelFactoriesEntryPoint.getHiltViewModelMap()
[com.xxx.App_HiltComponents.SingletonC ?
com.xxx.App_HiltComponents.ActivityRetainedC ?
com.xxx.App_HiltComponents.ViewModelC] 1 error
Api模块示例Hilt配置
@Module @InstallIn(SingletonComponent::class) object ApiClientModule { @Provides @Singleton fun bindNetworkManager( settings: ISettings, versionProvider: VersionProvider ): INetworkManager { return NetworkManager(settings, versionProvider) } ... }
问题根源与解决方法
问题根源
你写的CoreModule里的bindVersionProvider方法完全多余——VersionProvider已经有带@Inject的构造函数,Hilt会自动识别并提供这个类的实例。而你用@Binds把VersionProvider绑定到自己,相当于告诉Hilt:要获取VersionProvider,需要先注入VersionProvider,这直接造成了循环依赖。
解决步骤
- 删除CoreModule中的bindVersionProvider方法:不需要手动绑定一个已经有@Inject构造的类到自身
- 确保VersionProvider是单例:如果需要这个类的实例全局唯一,直接在
VersionProvider类上添加@Singleton注解即可,不需要通过模块绑定:
@Singleton class VersionProvider @Inject constructor(@ApplicationContext context: Context) { // ... 原有代码 }
这样修改后,Hilt会直接通过构造函数创建单例的VersionProvider实例,不会再出现循环依赖问题。
内容的提问来源于stack exchange,提问作者Morten Holmgaard

