Кинжал отсутствует привязка при добавлении AndroidInjector - PullRequest
2 голосов
/ 01 июля 2019

У меня следующая проблема: я начал изучать Dagger 2 и пытался добавить инъекции в свой класс приложений.Вот код моего класса приложения:

class TraktTvApp : Application(), HasActivityInjector {

    @Inject
    lateinit var androidInjector: AndroidInjector<Activity>

    override fun activityInjector(): AndroidInjector<Activity>? = androidInjector

    override fun onCreate() {
        super.onCreate()

        appContext = applicationContext
        instance = this

        initStetho()
        initFabric()

        DaggerAppComponent
                .builder()
                .application(this)
                .build()
                .inject(this)

        FirebaseInstanceId.getInstance().instanceId
                .addOnCompleteListener(OnCompleteListener { task ->

                    if (!task.isSuccessful) {
                        return@OnCompleteListener
                    }

                    val token = task.result?.token
                }
                )
    }

    private fun initFabric() {
        Fabric.with(this, Crashlytics(), CrashlyticsNdk())
    }

    private fun initStetho() {
        if (BuildConfig.DEBUG) {
            Stetho.initializeWithDefaults(this)
        }
    }

    companion object {
        lateinit var instance: TraktTvApp
        lateinit var appContext: Context
    }

}

В этом классе у меня есть appContext как свойство, и я пытаюсь заменить его на инъекцию.Для этого я добавил следующие строки:

DaggerAppComponent .builder () .application (this) .build () .inject (this)

Когда я строил свое приложение, все было в порядке, но когда ядобавил

    @Inject
    lateinit var androidInjector: AndroidInjector<Activity>

    override fun activityInjector(): AndroidInjector<Activity>? = androidInjector

И попытался собрать Я получил эту ошибку:

public abstract interface AppComponent {
                ^
      dagger.android.AndroidInjector<android.app.Activity> is injected at
          com.mikhailovskii.trakttv.TraktTvApp.androidInjector
      com.mikhailovskii.trakttv.TraktTvApp is injected at
          com.mikhailovskii.trakttv.di.AppComponent.inject(com.mikhailovskii.trakttv.TraktTvApp)

Я уже видел возможные решения, но ни одно из них мне не помогло.Вот код моего AppModule:

@Module
class AppModule {

    @Singleton
    @Provides
    fun provideContext(application: TraktTvApp): Context {
        return application.applicationContext
    }

}

А вот AppComponent:

@Singleton
@Component(
        modules = [
            AndroidSupportInjectionModule::class,
            AppModule::class
        ]
)
interface AppComponent {

    @Component.Builder
    interface Builder {

        @BindsInstance

        fun application(application: TraktTvApp): Builder

        fun build():AppComponent

    }

    fun inject(application: TraktTvApp)

}

Итак, в чем проблема и как я могу ее решить?

1 Ответ

2 голосов
/ 01 июля 2019

Вам не нужно добавлять AndroidInjector вручную.Вы можете использовать базовые классы Dagger, чтобы Dagger справился с ним за вас

Вы должны расширить свой класс Application с DaggerApplication

 class MyApp: DaggerApplication() {

    /**
     * Returns the injector
     */
    override fun applicationInjector(): AndroidInjector<out DaggerApplication> {

        val appComponent = DaggerAppComponent.builder().application(this).build()
        appComponent.inject(this)

        return appComponent

    }

Также ваш Main Component расширяет AndroidInjector

/**
 * The main component that holds and services all modules within its builder.
 */
@Singleton
@Component(modules = [AndroidSupportInjectionModule::class])
interface AppComponent : AndroidInjector<MyApp> {

    /**
     * A {@see [Component.Builder]} that initializes necessary implementations
     */
    @Component.Builder
    interface Builder {

        @BindsInstance
        fun application(application : Application) : Builder
        fun build() : AppComponent
    }

}

Если вы хотите использовать Context, вы можете добавить его в свой AppModule

@Module
class AppModule {

    @Singleton
    @Provides
    fun provideContext(application: Application): Context {
        return application.applicationContext
    }

}
...