添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
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

After spending a ludicrous amount of time trying to figure out why my dagger injections weren't working; I realised that the "object" type in Kotlin was the problem.

The following did not work, the injected "property" was null.

object SomeSingleton {
    @Inject
    lateinit var property: Property
    init {
        DaggerGraphController.inject(this)

However, the following DID work just fine:

class NotSingleton {
    @Inject
    lateinit var property: Property
    init {
        DaggerGraphController.inject(this)

I tried google, I tried the documentation but I could not pin point the reason behind this. Also note that I havent tried this with JAVA, JAVA doesnt have the concept of singletons built in anyway.

Why is this the case? Why is a kotlin singleton unable to inject members but a regular non-singleton class can?

Sounds like object.init runs sooner than the initialization of your DaggerGraphController thing. – EpicPandaForce Oct 11, 2019 at 14:24

If you look into kotlin bytecode you'll find that the code you've written is translated into following:

public final class SomeSingleton {
    public static LProperty; property // <- Notice static field here
    public final getProperty()LProperty
    public final setProperty(LProperty)V

As you can see the actual field is static which makes it uneligible for instance injection. You may try to move @Inject annotation onto setter method by doing so:

object SomeSingleton {
    @set:Inject
    lateinit var property: Property
                this still didnt work, the first time around I got an uninitialized field error...after that, a NoClassDefFoundError  i even tried with @field:Inject, same negative result unfortunately
– Nihilanth
                Jan 24, 2018 at 3:47
                Doen't work for me. Exception during compilation Caused by: java.lang.IllegalArgumentException 	at com.google.common.base.Preconditions.checkArgument(Preconditions.java:128) 	at dagger.internal.codegen.writing.InjectionMethod.invoke(InjectionMethod.java:112) 	at dagger.internal.codegen.writing.InjectionMethods$InjectionSiteMethod.invoke(InjectionMethods.java:358)
– Alex
                May 7, 2020 at 14:32

A workaround for this can be to extend a BaseClass that consists of the fields to be injected.

object SomeSingleton : BaseClass {
open class BaseClass{
    @Inject
    lateinit var property: Property
    init{
        YourDaggerComponent.inject(this)

This does work, although this would leak this, which comes up as an android studio warning, to get rid of that make the Base class abstract and instead inject the fields in your original object class

object SomeSingleton : BaseClass {
 // Add the init block here instead of the base class
 init{
        YourDaggerComponent.inject(this)
abstract class BaseClass{
    @Inject
    lateinit var property: Property
   //Remove the init block from here

And you Dagger AppComponent interface can be like, any of those function def should work

interface Component{
    fun inject(someSingleton : SomeSingleton)
    fun inject(baseClass: BaseClass)

I hope this helps....

I just get this error when trying to inject into a kotlin object: Dagger does not support injection into Kotlin objects. This is on Dagger 2.27. – mco May 30, 2020 at 4:57 Doesn't work for me, exception returns: lateinit property [variable] has not been initialized – Jakub Kostka Jan 6, 2021 at 10:32

This was previously allowed by a bug in Dagger. As others described, it is because the properties in a kotlin object are backed by static fields.

See https://github.com/google/dagger/issues/1665 for the fix. It was fixed in 2.27.

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.