我是Dagger 2的新手,我正在尝试与Kotlin学习。首先让我解释一下我的项目结构。我有一个类名“ Info”:
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中,我为“信息”注入了两个字段
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")
}
}
现在,汽车课需要引擎和车轮。所以下面是Engine和Wheel类
引擎类别:
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类的“ 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现在却显示有关info字段注入或Info类的错误。我知道它也对“ 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)