首页 > 解决方案 > 在 Android Studio 中将 Dagger 2 与 Kotlin 一起使用时出错

问题描述

我是 Dagger 2 的新手,我正在尝试使用 Kotlin 学习它。让我先解释一下我的项目结构。我有一个类名“信息”:

class Info constructor(var message: String) {}

我为此类“InfoModule”创建了一个模块

    @Module
    class InfoModule {

        @Provides @Choose("HELLO")
        fun sayHello(): Info{
            return Info(message = "Hello dagger 2")
        }

        @Provides @Choose("HI")
        fun sayHi(): Info{
            return Info(message = "Hi dagger 2")
        }
}

我为这个模块创建了一个名为“MagicBox”的组件接口

  @Component(modules = [InfoModule::class])
interface MagicBox {
    fun poke(app: MainActivity)
}

然后在 MainActivity 中,我为“Info”注入了两个字段

 class MainActivity : AppCompatActivity() {



    var textView: TextView? = null;

    @Inject @field:Choose("HELLO") lateinit var infoHello: Info
    @Inject @field:Choose("HI") lateinit var infoHi: Info


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)


        DaggerMagicBox.create().poke(this)

        textView = findViewById<TextView>(R.id.textView)
        textView!!.text = infoHi.message

    }
}

@Qualifier
@MustBeDocumented
@kotlin.annotation.Retention(AnnotationRetention.RUNTIME)
annotation class Choose(val value: String)

正如您在上面看到的,我创建了一个@Choose 注释来了解@Qualifier 的工作原理。到目前为止,代码运行良好,它真的是 Dagger 的魔力:)。

问题从这里开始:>> 然后我决定在 MainActivity 中注入另一个名为“car”的字段,就像在 MainActivity 中注入“info”字段一样。要做到这一点,我需要一个汽车类。

    class Car constructor(var engine: Engine, var wheels: Wheels) {

fun drive(){
    Log.d("Car","Driving")
}
}

现在汽车类需要发动机和车轮。所以下面是引擎和车轮类

发动机等级:

class Engine  {
}

轮组:

    class Wheels  {
}

然后我为汽车类创建了一个模块

 @Module
class CarModule {

@Provides
fun provideEngine(): Engine{
   return Engine()
}

@Provides
fun provideWheel(): Wheels{
    return Wheels()
}

@Provides @Choose("NewCar")
fun provideCar(engine: Engine, wheels: Wheels): Car{
    Log.d("NewCar", "Created")
    return Car(engine, wheels)
}

}

汽车的组件如下

 @Component (modules = [CarModule::class])
interface CarComponent {

    fun injectCar(mainActivity: MainActivity)


}

然后我在 MainActivity 中注入了 car 字段,并尝试调用 Car 类的“驱动”方法。现在我的 MainActivity 看起来像这样。

    class MainActivity : AppCompatActivity() {



    var textView: TextView? = null;


    @Inject @field:Choose("HELLO") lateinit var infoHello: Info
    @Inject @field:Choose("HI") lateinit var infoHi: Info

    @Inject @field:Choose("NewCar") lateinit var  car: Car

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)


        DaggerMagicBox.create().poke(this)
        textView = findViewById<TextView>(R.id.textView)
        textView!!.text = infoHi.message


        DaggerCarComponent.create().injectCar(this)
        car.drive()


    }
}

@Qualifier
@MustBeDocumented
@kotlin.annotation.Retention(AnnotationRetention.RUNTIME)
annotation class Choose(val value: String)

MakeProject 后的 Logcat 错误:

    error: [Dagger/MissingBinding] @de.test.testtheapp.Choose("HELLO") de.test.testtheapp.Api.Info cannot be provided without an @Provides-annotated method.
public abstract interface CarComponent {
                ^
      @de.test.testtheapp.Choose("HELLO") de.test.testtheapp.Api.Info is injected at
          de.test.testtheapp.MainActivity.infoHello
      de.test.testtheapp.MainActivity is injected at
          de.test.testtheapp.Components.CarComponent.injectCar(de.test.testtheapp.MainActivity)

我真正感到奇怪的是,虽然“信息”字段注入之前工作得很好,但为什么在添加汽车字段注入后,logcat 现在显示有关信息字段注入或信息类的错误。我知道它也谈到了“CarComponent”。现在没有任何工作。甚至“DaggerMagicBox”也没有解决。我对这个错误一无所知,两天以来我一直坚持这一点。我对匕首的了解非常有限,我不知道解决方案是什么。如果有人给我一个线索,我将非常感激。我正在使用 Android Studio 3.5.1 和 Dagger 版本 2.21

标签: androidandroid-studiokotlindagger-2

解决方案


您正在尝试使用CarComponent注入以下依赖项MainActivity

DaggerCarComponent.create().injectCar(this)

但是您CarComponent没有办法提供Info

@Inject @field:Choose("HELLO") lateinit var infoHello: Info

因为提供者方法在其模块列表中定义InfoModule并且CarComponent没有它。


您正在使用两个组件来注入以下依赖项MainActivity

DaggerMagicBox.create().poke(this)
...
DaggerCarComponent.create().injectCar(this)

你应该只使用一个。

要么添加CarModule到模块列表中,要么MagicBox删除DaggerCarComponent.create().injectCar(this)

或添加InfoModule到模块列表CarComponent并删除DaggerMagicBox.create().poke(this)


推荐阅读