简体   繁体   English

在 Android Studio 中使用带有 Kotlin 的 Dagger 2 时出错

[英]Error using Dagger 2 with Kotlin in Android Studio

I am new to Dagger 2 and I am trying to learn it with Kotlin.我是 Dagger 2 的新手,我正在尝试使用 Kotlin 来学习它。 Let me explain my Project structure first.让我先解释一下我的项目结构。 I am having a Class name "Info":我有一个 Class 名称“信息”:

class Info constructor(var message: String) {}

I have created a module for this class "InfoModule"我为此 class “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")
        }
}

I have created a component interface for this module named "MagicBox"我为这个模块创建了一个名为“MagicBox”的组件接口

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

Then in the MainActivity I have injected the two fields for "Info"然后在 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)

As you see above I haved created a @Choose annotation to learn how @Qualifier works.正如您在上面看到的,我创建了一个@Choose 注释来了解@Qualifier 的工作原理。 Up to here the code works perfectly and it is really a magic of Dagger:).到目前为止,代码完美运行,它真的是 Dagger 的魔力:)。

PROBLEM STARTS HERE:>> Then I decided to Inject another field called "car" inside my MainActivity in the same way the "info" field is injected in the MainActivity.问题从这里开始:>> 然后我决定在 MainActivity 中注入另一个名为“car”的字段,就像在 MainActivity 中注入“info”字段一样。 To do that first i need a Car class.首先,我需要一辆汽车 class。

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

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

Now the car class needs Engine and Wheels.现在汽车 class 需要发动机和车轮。 So below are Engine and Wheel classes所以下面是引擎和车轮类

Engine Class:发动机 Class:

class Engine  {
}

Wheel Class:车轮 Class:

    class Wheels  {
}

Then I have created a Module for Car class然后我为汽车 class 创建了一个模块

 @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)
}

}

The component for Car is below汽车的组件如下

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

    fun injectCar(mainActivity: MainActivity)


}

Then I have injected the car field in the MainActivity and I have tried to called the "drive" method of Car class.然后我在 MainActivity 中注入了 car 字段,并尝试调用 Car class 的“驱动”方法。 Now my MainActivity looks like this.现在我的 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)

The Logcat Error after MakeProject: 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)

What i really find strange is that although the "info" field injection was working prefectly before, why after adding car field injection, the logcat is now showing error about info field injection or Info class.我真正感到奇怪的是,虽然“信息”字段注入之前工作得很好,但为什么在添加汽车字段注入后,logcat 现在显示有关信息字段注入或信息 class 的错误。 I know its also saying something about "CarComponent".我知道它也谈到了“CarComponent”。 Now nothing is working.现在没有任何工作。 Even the "DaggerMagicBox" is unresolved.甚至“DaggerMagicBox”也没有解决。 I am clueless about the error and I am stuck on this since two days.我对这个错误一无所知,两天以来我一直坚持这一点。 My knowledge about dagger is very limited that I don't know what is the solution.我对匕首的了解非常有限,我不知道解决方案是什么。 I will be very thankful if some give me a clue.如果有人给我一个线索,我将非常感激。 I am using Android Studio 3.5.1 and Dagger version 2.21我正在使用 Android Studio 3.5.1 和 Dagger 版本 2.21

You are trying to use CarComponent to inject dependencies of MainActivity :您正在尝试使用CarComponent注入MainActivity的依赖项:

DaggerCarComponent.create().injectCar(this)

But your CarComponent doesn't have a way to provide Info :但是您的CarComponent没有办法提供Info

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

Because the provider method is defined in InfoModule and CarComponent doesn't have it in its modules list.因为提供者方法是在InfoModule中定义的,而CarComponent在其模块列表中没有它。


You are using two components to inject the dependencies of MainActivity :您正在使用两个组件来注入MainActivity的依赖项:

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

You should only use one.你应该只使用一个。

Either add the CarModule to the list of modules of MagicBox and remove DaggerCarComponent.create().injectCar(this) .将 CarModule 添加到CarModule的模块列表中并删除MagicBox DaggerCarComponent.create().injectCar(this)

Or add the InfoModule to the list of modules of CarComponent and remove DaggerMagicBox.create().poke(this)或者将InfoModule添加到 CarComponent 的模块列表中并删除CarComponent DaggerMagicBox.create().poke(this)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM