上一部分目录内容
- 实施方法和领域
- 匕首中的延迟初始化
- 匕首模块。 当匕首听不懂你的话
- 摘要命名。 相同类型的多个实例
实施方法和领域第一部分描述了一种在构造函数级别实现依赖关系的方法。 另外,匕首可以实现字段和方法的依赖关系。 但是,在绝对必要时应使用这些实现。
方法实现示例:
class Car @Inject constructor(private var engine: Engine){ var key: Key? = null @Inject set } class Key @Inject constructor()
在上面的示例中,为关键字段实现了set方法的依赖关系
字段的实现分为三个阶段:
- 将嵌入方法添加到抽象工厂
- 定义要实施的字段
- 在抽象类匕首实现中使用实现方法来实现依赖关系
显然,为了更容易理解这一点,
1.在我们的抽象类中,为MainActivity添加一个实现方法
@Component interface DaggerComponent { fun getCar(): Car fun getEngine(): Engine fun getFuel(): Fuel fun inject(act: MainActivity) }
2.定义应在MainActivity中实现的字段。 注入的字段必须为lateinit var,并且对所有人(公共)可见
@Injected lateinit var car: Car
3.我们调用抽象类的添加方法inject()来实现活动字段。
最终,我们的MainActivity类将看起来像一条痕迹。 方式:
class MainActivity : AppCompatActivity() { @Inject lateinit var car: Car override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) DaggerDaggerComponent.create().inject(this) } }
匕首中的延迟初始化如您所知,启动应用程序时,并非总是需要所有类的实例。 这样可以加快首次启动速度,并提高速度。 匕首中有2种类型的嵌入式对象初始化:提供者<>和懒惰<>
提供程序 -首次调用该对象时会进行初始化,并且每次调用都会返回该对象的新实例
惰性 -首次调用时发生初始化,然后返回之前缓存的实例
要使用这些类型的初始化,必须以所需的形式“包装”初始化的对象。
提供者用法示例:
class Engine @Inject constructor(private var fuel: Fuel){ fun start(){ if(fuel!=null){ print("Started!") }else{ print("No more fuel!") } } } class Car @Inject constructor(private var engine: Provider<Engine>){ var key: Key? = null @Inject set fun startCar(){ engine.get().start() } } class Key @Inject constructor()
每次调用get()方法时,我们都会获得所需对象的新实例。
使用懒惰的示例:
class Fuel @Inject constructor() { val fuelType = if(BuildConfig.DEBUG){ "benzine" }else{ "diesel" } } class Engine @Inject constructor(private var fuel: Lazy<Fuel>){ fun start(){ if(fuel!=null){ print("Started with ${fuel.get().fuelType}") }else{ print("No more fuel!") } } }
每次调用get()方法时,我们都会获得相同的实例。
注意! 在Android Studio中添加惰性视图的get()方法时,该方法可能会用红色下划线,因为 Kotlin具有自己的惰性类。 所以我们导入匕首类
import dagger.Lazy
匕首模块。 当匕首听不懂你的话有时候,匕首无法理解您的意图。 例如,我们的Car类具有一个(接口)Driver类型的字段,该字段由Ivanov类继承
当您尝试使用接口类型实现字段时,会出现错误“没有@ Provides注释的方法就无法提供”。
为了解决这个问题,匕首建议使用模块。 这些模块为匕首提供了无法单独获取的其他信息。 作为模块,您可以使用接口或对象(对象)。
要解决以上问题,请创建一个模块:
@Module interface DaggerModul { @Binds fun bindDriver(driver: Ivanov): Driver } class Ivanov @Inject constructor(): Driver
在bindDriver方法中,我们解释了如何用匕首初始化接口。
此外,在组件中,您需要列出所有现有的匕首模块
@Component(modules = [DaggerModul::class]) interface DaggerComponent { … }
假设对于我们的Engine类,使用了第三方库圆柱体(接口)的字段。 如果不清楚在运行时将初始化哪个类,那么如何为Dagger描述此类字段?
到目前为止,我们已经使用注释来解释匕首应该如何注入依赖项。 例如,如果您不知道如何从外国图书馆创建类怎么办?
提供注释描述了当您需要显式描述要初始化的类的实例时的情况。
@Module object DaggerModuleObject { @Provides @JvmStatic fun getBoschCylinder(): Cylinder = BoschCylinder() }
因此,我们告诉匕首,当初始化圆柱体字段时,我们需要BoschCylinder类的实例。
摘要名为 。 相同类型的多个实例有时您需要使用不同的设置来创建同一类的实例。 在我们的示例中,这些是车身和门上的不同颜色。
尝试使用跟踪构建项目时。 模块将收到错误“(我们的类)颜色被绑定多次”
@Provides @JvmStatic fun getColorRed():Color = Color("red") @Provides @JvmStatic fun getColorBlue():Color = Color("blue")
为了解决这种情况,使用了
Named注释。 首先,在模块中,我们将创建3个新的方法以使用dagger进行初始化
@JvmStatic @Provides fun getColor(): Color = Color("") @Provides @Named("blueColor") @JvmStatic fun getColorBlue(): Color{ return Color("blue") } @JvmStatic @Named("redColor") @Provides fun getColorRed(): Color = Color("red")
第一个方法是默认方法,没有它的话,匕首会发誓说缺少类“没有Inject构造函数或Provides注释方法无法提供”
以下两个方法返回相同类的实例。 仍然需要在适当的地方添加此类的实现,并使用
命名为Named的注释进行调用
class Door @Inject constructor() { @Named("blueColor") @Inject lateinit var color:Color } class Car @Inject constructor(private var engine: Provider<Engine>, private var door: Door, var driver: Driver){ var key: Key? = null @Inject set @Inject @Named("redColor") lateinit var color: Color fun startCar(){ engine.get().start() } } class Key @Inject constructor()
源代码