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

Dagger 2.16多Activity注入报错:匹配绑定存在却提示缺失

Dagger 2.16 注入报错:MissingBinding for Fragment Injector Map

我用Dagger 2.16实现依赖注入,参考了一篇Medium文章,只有HomeActivity时一切正常,但添加SplashScreenActivity并接入Dagger后出现了构建报错。

项目相关代码

AppComponent.kt

@Singleton @Component(modules = [ AndroidInjectionModule::class, AppModule::class, ActivityBuilder::class, ServiceBuilder::class, BroadcastRecieverBuilder::class]) 
interface AppComponent : AndroidInjector<MyApp> { 
    @Component.Builder 
    abstract class Builder : AndroidInjector.Builder<MyApp>() 
}

AppModule.kt

@Module() 
class AppModule { 
    @Provides @Singleton 
    fun provideContext(application: MyApp): Context { 
        return application 
    } 
    @Provides @Singleton 
    fun provideRestService(retrofit: Retrofit): RestService { 
        return retrofit.create(RestService::class.java) 
    } 
    ... 
}

ActivityBuilder.kt

@Module 
abstract class ActivityBuilder { 
    @ContributesAndroidInjector(modules = [HomeActivityModule::class]) 
    @PerActivity 
    abstract fun bindHomeActivity(): HomeActivity 

    @ContributesAndroidInjector(modules = [SplashScreenModule::class]) 
    @PerActivity 
    abstract fun bindSplashActivity(): SplashScreenActivity 
}

BaseActivity.kt

abstract class BaseActivity<V : BaseView, P : MvpBasePresenter<V>> : MvpActivity<V, P>(), BaseView, HasSupportFragmentInjector { 
    @Inject lateinit var fragmentInjector: DispatchingAndroidInjector<Fragment> 
    @Inject lateinit var mPresenter: P 

    override fun onCreate(savedInstanceState: Bundle?) { 
        AndroidInjection.inject(this) 
        super.onCreate(savedInstanceState) 
    } 

    override fun createPresenter(): P = mPresenter 

    override fun supportFragmentInjector(): AndroidInjector<Fragment> { 
        return fragmentInjector 
    } 
}

注:我没有使用DaggerActivity,而是自定义BaseActivity继承自Mosby的MvpActivity。

SplashScreenModule.kt

@Module 
abstract class SplashScreenModule { 
    @Binds @PerActivity 
    internal abstract fun splashPresenter(splashPresenter: SplashScreenPresenter): BasePresenter<*> 
}

HomeActivityModule.kt

@Module 
abstract class HomeActivityModule { 
    @Binds @PerActivity 
    internal abstract fun homePresenter(homePresenter: HomeActivityPresenter): BasePresenter<*> 

    @ContributesAndroidInjector(modules = [DownloadFragmentModule::class]) 
    @PerFragment 
    internal abstract fun downloadsFragment(): DownloadsFragment 
}

构建报错信息

error: [Dagger/MissingBinding] [dagger.android.AndroidInjector.inject(T)] java.util.Map<java.lang.Class<? extends android.support.v4.app.Fragment>,javax.inject.Provider<dagger.android.AndroidInjector.Factory<? extends android.support.v4.app.Fragment>>> cannot be provided without an @Provides-annotated method.
public abstract interface AppComponent extends dagger.android.AndroidInjector<com.realtime.app.MyApp> {
^
A binding with matching key exists in component: com.realtime.dagger.ActivityBuilder_BindHomeActivity.HomeActivitySubcomponent
java.util.Map<java.lang.Class<? extends android.support.v4.app.Fragment>,javax.inject.Provider<dagger.android.AndroidInjector.Factory<? extends android.support.v4.app.Fragment>>> is injected at
dagger.android.DispatchingAndroidInjector.<init>(injectorFactories)
dagger.android.DispatchingAndroidInjector<android.support.v4.app.Fragment> is injected at
com.realtime.core.BaseActivity.fragmentInjector
com.realtime.splashScreen.SplashScreenActivity is injected at
dagger.android.AndroidInjector.inject(T)
component path: com.realtime.dagger.AppComponent → com.realtime.dagger.ActivityBuilder_BindSplashActivity.SplashScreenActivitySubcomponent

我试过查看类似问题,但没法对应到自己的场景,请问我遗漏了什么?

更新:目前我让SplashScreenActivity不继承BaseActivity,避免注入fragmentInjector: DispatchingAndroidInjector<Fragment>,暂时可以正常运行,因为SplashScreenActivity中没有Fragment。


问题原因与解决方案

其实问题出在你的BaseActivity实现了HasSupportFragmentInjector接口,并且注入了DispatchingAndroidInjector<Fragment>,但SplashScreenActivity的子组件里没有任何Fragment的注入绑定。

Dagger在生成SplashScreenActivitySubcomponent的时候,发现需要提供Map<Class<? extends Fragment>, Provider<AndroidInjector.Factory<? extends Fragment>>>这个依赖,但SplashScreenModule里没有相关的Fragment贡献代码,也没有引入AndroidSupportInjectionModule(注意不是AndroidInjectionModule)到它的子组件中,所以Dagger找不到对应的绑定。

具体解决方案有两种,你可以根据需求选择:

方案1:给SplashScreen的子组件添加必要的模块

修改ActivityBuilder.kt中SplashScreen的@ContributesAndroidInjector,加入AndroidSupportInjectionModule::class:

@ContributesAndroidInjector(modules = [SplashScreenModule::class, AndroidSupportInjectionModule::class])
@PerActivity
abstract fun bindSplashActivity(): SplashScreenActivity

这个模块会提供Dagger需要的Fragment注入相关的基础绑定,即使你的SplashScreenActivity没有Fragment,也能满足DispatchingAndroidInjector的依赖需求。

方案2:拆分BaseActivity,区分带Fragment和不带Fragment的场景

既然SplashScreenActivity不需要处理Fragment,你可以创建两个BaseActivity:

  • 一个是带Fragment注入支持的BaseFragmentActivity(继承MvpActivity,实现HasSupportFragmentInjector,注入fragmentInjector),供HomeActivity这类有Fragment的页面继承;
  • 另一个是不带Fragment注入的BaseMvpActivity(只处理Presenter注入,不实现HasSupportFragmentInjector,也不注入fragmentInjector),供SplashScreenActivity这类无Fragment的页面继承。

这样更符合单一职责原则,也能避免不必要的依赖注入。

为什么HomeActivity没问题?

因为HomeActivityModule里有@ContributesAndroidInjector用于DownloadsFragment,Dagger会自动在HomeActivity的子组件中引入必要的Fragment绑定依赖,所以不会报错。而SplashScreen的子组件里没有任何Fragment相关的绑定,也没加AndroidSupportInjectionModule,就会出现MissingBinding的错误。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:34:33