I am trying to inject Context
using Dagger 2.
AppComponent.kt:
@Singleton
@Component(
modules = [
AppModule::class
]
)
interface AppComponent {
fun context(): Context
}
AppModule.kt:
@Module
class AppModule(private val application: Application) {
@Provides
@Singleton
fun providesApplicationContext(): Context = application
}
MainApp.kt:
class MainApp : Application() {
lateinit var appComponent: AppComponent
override fun onCreate() {
super.onCreate()
appComponent = initDagger()
}
private fun initDagger() = DaggerAppComponent.builder()
.appModule(AppModule(this))
.build()
}
Manager.kt: (Class where I want to inject Context
)
object Manager {
@Inject
lateinit var context: Context
}
However, I am getting following error:
error: Dagger does not support injection into static fields
public static android.content.Context context;
^
Is this because I am using an object
(Singleton)?
If you have any doubts related to question, please comment below. Thank you.
Is this because I am using an
object
(Singleton)?
Yes, object
s' properties are Java's static fields under the hood. Your Manager
class would decompile to something similar to:
public final class Manager {
@Inject
@NotNull
public static Context context;
public static final Manager INSTANCE;
static {
INSTANCE = new Manager();
}
private Manager() {
}
@NotNull
public final Context getContext() {
return context;
}
public final setContext(Context var1) {
context = var1;
}
}
and Dagger 2 simply does not support injection into static fields
. However, even if Dagger let you do it, the dependency wouldn't be satisfied. That's because Dagger won't be able to inject into an object unless is explicitly told to do so (like you do when injecting for example into activities) or creates the object by itself. Obviously the latter doesn't apply when it comes to Kotlin's object
s. In order to ask Dagger to inject the dependency you would have to somehow provide a MainApp
instance:
init {
mainApp.appComponent.inject(this)
}
which doesn't make much sense since you'd like to inject it (as a Context
) in the first place.
Therefore you have to either satisfy the dependency manually and don't bother with Dagger in this one or leave the object
idea behind, use just a standard class and let Dagger handle its scope:
@Singleton
class Manager @Inject constructor(private val context: Context) {
}
The only drawback is that you would have to inject a Manager
instance (created by Dagger) into every class that needs to use it instead of calling its methods statically.
It's because you are not injecting your Manager class in your AppModule.kt and also you need to pass the context.
Just like this:
@Module
class AppModule(private val application: Application) {
@Singleton
@Provides
fun providesManager(): Manager {
return Manager(application.applicationContext)
}
}
Obviously you need to change your Manager class to:
@Singleton
class Manager @Inject constructor(context: Context) {
//here you can use your context
}
And it should work
Additional:
You can remove this line in your AppComponent.kt:
fun context(): Context
Because it is not necessary and unused
the only disadvantage its that you will need to inject your Manager class in every activity/fragment you want to use it
Just like @jsamol said
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With