Reputation: 2465
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?
Upvotes: 3
Views: 5395
Reputation: 3115
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
}
}
Upvotes: 4