目录
0. 前言
1. 依赖与注入
2. @Inject
3. @Module & @Provides
4. @Component
5. @Qualifier
6. Provider & Lazy
7. @Scope
8. 注入到Set和Map容器
9. Bind系列注解
10. dagger中依赖关系与继承关系
11. dagger.android
再看@Component
我们之前使用@Component
都仅仅是在其注解的接口中添加一个inject
方法,作为进行依赖注入的入口,但@Component
的作用远不止如此
新需求
为了深入研究@Component
,我们新增两个需求
需求1
在
Activity
显示Computer
信息时,我们要求根据当前时间(System.currentTimeMillis()
)单双作为区别,如果单数就显示windows
,如果双数就显示linux
我们先考虑第一个需求,每次Activity.onCreate()
中都会调用inject()
方法注入windows
和linux
实例,但我们其实只用得上其中一个,这样岂不是造成了内存的浪费?不过不用担心,dagger为我们准备了Lazy
接口:
class CaseActivity : BaseActivity() {
@field:[Inject ComputerModule.WindowsComputerQualifier]
lateinit var windows: dagger.Lazy<Computer> // 注意这里是dagger.Lazy,因为Kotlin中也有Lazy接口,通常用于lazy标准委托,不是本篇的重点...
@field:[Inject ComputerModule.LinuxComputerQualifier]
lateinit var linux: dagger.Lazy<Computer>
@set:Inject
lateinit var timestamp: Date
/* ... */
private fun show() {
val builder = StringBuilder(timestamp.toString()).append("\n")
if (System.currentTimeMillis() % 2 == 0L) {
// 双数时显示linux
linux.get().execute(builder)
} else {
// 单数时显示windows
windows.get().execute(builder)
}
text_view.text = builder.toString()
}
}
我们可以在WindowsComputer
和LinuxComputer
初始化块中添加Log以验证是否有被实例化:
class WindowsComputer(price: Int) : Computer("Windows", price) {
init {
Log.i("Computer", "WindowsComputer: init") }
}
class LinuxComputer(price: Int) : Computer("Linux", price) {
init {
Log.i("Computer", "LinuxComputer: init") }
}
这里就不贴出实验结果了,相信大家都能猜到,也就是说dagger的@Component
是支持懒加载(Lazy
)的形式提供依赖注入的
接下来就是源码分析了,我们先看下用到的Lazy
接口和dagger生成的DaggerCaseActivityComponent
有什么变化:
/* dagger.Lazy */
public interface Lazy<T> {
T get(