Android + Hilt:注入Repository至Service引发依赖循环问题
问题根源拆解
你之前的核心问题是对Hilt构造注入的使用逻辑理解偏差,写了冗余的@Provides方法导致循环依赖,同时没必要地用EntryPoint绕开了Hilt的自动注入机制。
正确实现步骤
1. 为Repository启用构造注入
直接在Repository类上添加@Inject构造函数,Hilt会自动管理它的实例,无需额外写@Provides方法:
@Singleton class TrackRepository @Inject constructor( // 若有其他依赖(如Dao、OkHttpClient),直接在此添加参数,Hilt会自动注入 ) { // 你的Repository业务逻辑 }
2. 为Service启用构造注入
Service类同样通过@Inject构造函数依赖Repository,让Hilt自动完成注入:
@Singleton class MyService @Inject constructor( private val trackRepository: TrackRepository ) { // 你的Service业务逻辑 }
3. Activity中字段注入Service
给Activity添加@AndroidEntryPoint注解后,直接字段注入Service即可:
@AndroidEntryPoint class MainActivity : AppCompatActivity() { @Inject lateinit var myService: MyService // 生命周期方法及业务逻辑 }
4. 多模块适配注意事项
如果Repository在独立模块(如data模块):
- 在该模块的
build.gradle中添加Hilt依赖:implementation "com.google.dagger:hilt-android:2.48" kapt "com.google.dagger:hilt-android-compiler:2.48" - 无需额外配置模块,Hilt会跨模块识别带有
@Inject构造的类。
对之前错误写法的解释
循环依赖的原因:
你写的provideTrackRepository(trackRepository: TrackRepository): TrackRepository是完全冗余的——相当于告诉Hilt“要获取TrackRepository,先给我一个TrackRepository”,直接形成循环依赖,这种写法没有任何意义。手动实例化Repository的问题:
改成return TrackRepository()虽然能运行,但违背了依赖注入的核心规范:后续如果TrackRepository新增依赖,你必须手动修改这个方法,失去了Hilt自动管理依赖的优势。EntryPoint的正确使用场景:
EntryPoint仅用于在非Hilt注入的类(如普通工具类、未加@AndroidEntryPoint的类)中获取依赖。你的Service已经通过@Inject构造注入,完全不需要用EntryPoint去获取Repository。
最终依赖链流程
Activity(@AndroidEntryPoint)字段注入MyService → MyService(@Inject构造)自动注入TrackRepository → TrackRepository(@Inject构造)由Hilt自动管理实例,整个链路无需额外冗余代码。
内容的提问来源于stack exchange,提问作者Diego Perez

