Search code examples
androiddagger-2

Dagger-Android @ActivityKey not found, how to create Sub components explicitly


In dagger 2.25.2 can not find import dagger.android.ActivityKey so i cannot add a subcomponent explicitly, instead of using @ContributesInjector, using ApplicationModule

@Module(subcomponents = [MainActivitySubComponent::class], includes = [DummyDependencyModule::class])
abstract class AppModule {

    @Binds
    abstract fun bindContext(application: Application): Context

    @Binds
    @IntoMap
    @ActivityKey(MainActivity::class)
    abstract fun bindInjectorFactory(builder: MainActivitySubComponent.Builder)
            : AndroidInjector.Factory<out Activity>

    @Module
    companion object DummyDependencyModule {
        @Provides
        fun provideDummyDependency(context: Context): DummyDependency {
            return DummyDependency(context)
        }
    }

}

Application Component is

@Component(modules = [AndroidSupportInjectionModule::class, AppModule::class])
interface AppComponent : AndroidInjector<DaggerApplication> {

    @Component.Builder
    interface Builder {

        @BindsInstance
        fun application(application: Application): Builder

        fun build(): AppComponent
    }
}

MainActivity sub component is

@Subcomponent
interface MainActivitySubComponent : AndroidInjector<MainActivity> {
    @Subcomponent.Builder
    abstract class Builder : AndroidInjector.Builder<MainActivity>()
}

I created an ActivityKey since it couldn't find the one from Dagger library

with error

error: cannot find symbol, @ActivityKey(MainActivity.class) ^ symbol: class ActivityKey location: class ApplicationModule

@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.PROPERTY_GETTER)
@Retention(AnnotationRetention.RUNTIME)
@MapKey
internal annotation class ActivityKey(val value: KClass<out Activity>)

And the error is

IllegalArgumentException: No injector factory bound for Class<cMainActivity>

Solution

  • After inspecting the generated code i found that it's now used as @ClassKey in AppModule

    @ClassKey(MainActivity::class)
    abstract fun bindInjectorFactory(builder: MainActivitySubComponent.Builder)
            : AndroidInjector.Factory<*>
    

    instead of

      @Binds
        @IntoMap
        @ActivityKey(MainActivity::class)
        abstract fun bindInjectorFactory(builder: MainActivitySubComponent.Builder)
                : AndroidInjector.Factory<out Activity>
    

    and ClassKey code is

    @Documented
    @Target(METHOD)
    @Retention(RUNTIME)
    @MapKey
    public @interface ClassKey {
      Class<?> value();
    }