使用Dagger Hilt注入依赖时Fragment View Binding未初始化报错如何解决?
问题根因
你遇到的异常核心原因是存在两个完全独立的SearchFragment实例,Presenter持有的是未执行生命周期的无效实例:
- SearchModule中的
provideView方法手动创建了一个SearchFragment实例,这个实例不会被添加到Activity的Fragment管理器中,永远不会执行onCreateView生命周期,因此它的mBinding属性永远不会被初始化。 - SearchPresenter被加上了
@ActivityScope注解,整个Activity生命周期内只会生成一个Presenter实例,该实例持有的View就是上面提到的无效SearchFragment实例。 - Activity中
@Inject的mSearchFragment是Hilt生成的另一个正常实例,它会正常走生命周期、初始化mBinding,但它内部注入的Presenter持有的是之前的无效实例。当文本变更触发mPresenter.search时,回调的是无效实例的onSearchResult方法,就会抛出mBinding未初始化的异常。
你移除注入、手动创建Presenter时问题消失,是因为手动创建Presenter传入的this是当前正在运行的有效Fragment实例,回调自然正常。
修复方案
- 删掉错误的SearchModule配置,不需要手动Provides View和Presenter。
- 给SearchFragment加上
@AndroidEntryPoint注解,这是Hilt在Fragment中进行注入的必须配置:
@AndroidEntryPoint class SearchFragment : Fragment(), SearchContract.View { // 原有代码不变,不需要加@Inject构造方法 // ... }
- Activity不要通过注入获取Fragment实例,直接创建实例提交事务即可,Hilt会在Fragment attach到Activity时自动完成它的依赖注入:
@AndroidEntryPoint class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) supportFragmentManager .beginTransaction() .replace(R.id.main_fragment_container, SearchFragment()) .commit() } }
- 如果你需要通过Hilt注入Presenter时自动关联当前Fragment作为View,新增Fragment级别的Module绑定View实现,同时调整Presenter的作用域为FragmentScope:
@Module @InstallIn(FragmentComponent::class) abstract class SearchFragmentModule { @Binds abstract fun bindSearchView(fragment: SearchFragment): SearchContract.View } // 调整Presenter注解 @FragmentScope class SearchPresenter @Inject constructor(private val mView: SearchContract.View) : SearchContract.Presenter { // 原有逻辑不变 // ... }
内容的提问来源于stack exchange,提问作者kc_dev
相关产品推荐
相关产品推荐

