Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I have the following problem: I started to study Dagger 2 and trying to add injections to my App class. Here's the code of my App class:

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

In this class I have appContext as Property and I am trying to replace it with injection. For this purpose I added this lines

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

When I build my App everything was ok, but when I added

    @Inject
    lateinit var androidInjector: AndroidInjector<Activity>
    override fun activityInjector(): AndroidInjector<Activity>? = androidInjector

And tried to build I got this error:

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)

I have already seen possible solutions, but none of them helped me. Here's the code of my AppModule:

@Module
class AppModule {
    @Singleton
    @Provides
    fun provideContext(application: TraktTvApp): Context {
        return application.applicationContext

And here's 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)

So, what's the problem and how can I solve it?

You do not need to add AndroidInjector manually. You can use Dagger base classes so Dagger will handle it for you

You should extend your Application class from 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

Also your Main Component extends 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

If you want to use Context, you can add it your AppModule

@Module
class AppModule {
    @Singleton
    @Provides
    fun provideContext(application: Application): Context {
        return application.applicationContext
                Yes, thanks a lot, but can you explain me also what way should I get the context now? Before I did in in the following way: TraktTvApp.appContext and now I should do it in what way? I tried this:             AppModule().provideContext(TraktTvApp()), but I don't think this is the right way
– Sergei Mikhailovskii
                Jul 1, 2019 at 19:38
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.