Android Hilt 循环依赖问题:用接口回调实现Fragment与注入类通信报错
问题根因
当前代码形成了完整的依赖闭环:
MyFragment实例化时需要注入MyClass实例MyClass实例化时需要注入MyInterface实例- Hilt模块中绑定的
MyInterface实现就是当前正在创建的MyFragment实例
Hilt无法按顺序完成实例创建,因此触发循环依赖错误。
可行解决方案
方案1:懒加载注入(代码改动最小)
将MyFragment中MyClass的注入改为Dagger提供的懒加载模式,仅在首次使用时才创建MyClass实例,此时MyFragment已经完成实例化,可以正常作为MyInterface实现注入到MyClass中:
@AndroidEntryPoint class MyFragment : Fragment(), MyInterface { // 注意使用Dagger提供的Lazy,不要用Kotlin标准库的lazy @Inject lateinit var myClass: dagger.Lazy<MyClass> // 实际使用时调用get()获取实例 fun testFunc() { myClass.get().doSomething() } }
其余原有代码无需修改,即可解决循环依赖问题。
注意:不要在
MyFragment的构造函数、onAttach等过早生命周期节点调用myClass.get(),否则仍会触发循环依赖。
方案2:手动设置回调(更符合Android组件规范)
移除Hilt对MyInterface的注入绑定,改为手动设置回调,彻底消除依赖闭环,同时也能避免潜在的内存泄漏问题:
- 修改
MyClass代码,移除构造参数中的MyInterface,新增回调设置、清空方法:
class MyClass @Inject constructor() { var myInterface: MyInterface? = null fun clearCallback() { myInterface = null } }
- 删除
MyModule中MyInterface的绑定代码 - 在
MyFragment的生命周期中手动绑定、解绑回调:
@AndroidEntryPoint class MyFragment : Fragment(), MyInterface { @Inject lateinit var myClass: MyClass override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) myClass.myInterface = this } override fun onDestroyView() { // 销毁时主动清空回调,避免内存泄漏 myClass.clearCallback() super.onDestroyView() } }
内容的提问来源于stack exchange,提问作者Majid Sadeghi
相关产品推荐
相关产品推荐

