在 Android Studio 中将 Dagger 2 与 Kotlin 结合使用时出错
Error using Dagger 2 with Kotlin in Android Studio
我是 Dagger 2 的新手,我正在尝试使用 Kotlin 来学习它。让我先解释一下我的项目结构。我有一个 Class 名字 "Info":
class Info constructor(var message: String) {}
我为此创建了一个模块 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")
}
}
我已经为这个名为 "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.
class Car constructor(var engine: Engine, var wheels: Wheels) {
fun drive(){
Log.d("Car","Driving")
}
}
现在汽车 class 需要发动机和车轮。下面是引擎和车轮 classes
引擎Class:
class Engine {
}
轮Class:
class Wheels {
}
然后我为汽车创建了一个模块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)
}
}
汽车的组件如下
@Component (modules = [CarModule::class])
interface CarComponent {
fun injectCar(mainActivity: MainActivity)
}
然后我在 MainActivity 中注入了 car 字段,并尝试调用 Car class 的 "drive" 方法。
现在我的 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)
我真正觉得奇怪的是,虽然"info"字段注入之前工作得很好,为什么在添加汽车字段注入后,logcat现在显示有关信息字段注入或信息[的错误=62=]。我知道它也在说一些关于 "CarComponent" 的事情。现在没有任何工作。甚至 "DaggerMagicBox" 也未解决。我对这个错误一无所知,两天以来我一直坚持这个问题。我对匕首的了解非常有限,我不知道解决方案是什么。如果有人给我线索,我将不胜感激。我正在使用 Android Studio 3.5.1 和 Dagger 版本 2.21
您正在尝试使用 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)
我是 Dagger 2 的新手,我正在尝试使用 Kotlin 来学习它。让我先解释一下我的项目结构。我有一个 Class 名字 "Info":
class Info constructor(var message: String) {}
我为此创建了一个模块 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")
}
}
我已经为这个名为 "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.
class Car constructor(var engine: Engine, var wheels: Wheels) {
fun drive(){
Log.d("Car","Driving")
}
}
现在汽车 class 需要发动机和车轮。下面是引擎和车轮 classes
引擎Class:
class Engine {
}
轮Class:
class Wheels {
}
然后我为汽车创建了一个模块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)
}
}
汽车的组件如下
@Component (modules = [CarModule::class])
interface CarComponent {
fun injectCar(mainActivity: MainActivity)
}
然后我在 MainActivity 中注入了 car 字段,并尝试调用 Car class 的 "drive" 方法。 现在我的 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)
我真正觉得奇怪的是,虽然"info"字段注入之前工作得很好,为什么在添加汽车字段注入后,logcat现在显示有关信息字段注入或信息[的错误=62=]。我知道它也在说一些关于 "CarComponent" 的事情。现在没有任何工作。甚至 "DaggerMagicBox" 也未解决。我对这个错误一无所知,两天以来我一直坚持这个问题。我对匕首的了解非常有限,我不知道解决方案是什么。如果有人给我线索,我将不胜感激。我正在使用 Android Studio 3.5.1 和 Dagger 版本 2.21
您正在尝试使用 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)