2.5 Hilt 的内置组件和作用域
2.5.2 使注入对象单例
2.5.3 作用域的包含关系
2.6 Hilt 预置的 Qualifier
3 小结
参考文章
Git学习地址:传送门
1. 概述
=======================================================================
随着Android 11 的发布,Jetpack家族新添了 Hilt
和 App Startup
等成员。
而 Hilt 是被定义为 依赖注入框架而被发布。什么?又是依赖注入框架?不是之前已经有了一个 Dagger2
了吗?除了 Dagger2, 还有 ButterKnife
,Kotlin甚至还有轻量级的 Koin
。
为什么?为什么谷歌这么 这么的想让我们去了解依赖注入,并使用依赖注入的框架呢?下面请听我慢慢分析。
1.1 依赖注入(DI)概念
什么是依赖注入?先来看下面代码:
class MyClass {
val user = User()
}
我们在一个类 MyClass
中 声明了一个变量 user,并初始化-------调用 User
构造函数,创建一个对象。
上面这段代码就产生了一个依赖关系。
我们要先看懂谁依赖了谁?首先 MyClass
是我们的类,User
可以是我们自己写的类,也可以是通过第三方Jar包或SDK里面的类。
在我们写的 MyClass
的代码里面,我们需要一个 User 对象来完成一些任务,所以我们创建了 User 对象,这就说明 MyClass 依赖了 User。对于 MyClass来说,User是外面之物,但是又需要依赖它。
如果上面这个 User,不是由自己创建,而是由外部创建,然后在本类只做赋值工作 ,这个过程就是 依赖注入。
有一个我们非常熟悉的设计模式,就使用了依赖注入的方法—工厂模式:
class UserFactory {
fun newUser(): User{
return User()
}
}
class MyClass {
val user = UserFactory.newUser()
}
我们的 MyClass 类需要使用 User 类,但是这次没有自己来创建(没有自己new出来),而是交由给 UserFactory
来创建出来,MyClass就做了最后的赋值工作。
对于 MyClass 来说,这就是一次依赖注入,和上面例子相比,把对象创建的过程交由给了别的类。
所以我们通过上面两个例子就能知道依赖注入的本质是什么:借由外部得到对象。依赖注入框架就是这个外部
现在流行的 Dagger2、Koin框架,只是让我们更轻松、更容易的去得到对象。
Dagger的中文翻译是 “刀”,它就像一把刀,插进我们代码中。那相信你也知道 ButterKnife
为什么这么取名了吧。
PS: 对于我来说,针筒注射更适合来描述这个过程。
1.2 为什么在代码中使用外部去注入依赖
举一个Andorid常用的例子。 在 MVP / MVC / MVVM
架构没有流行之前,我们的代码都是如何的?
我们会把所有的 数据逻辑代码、视图代码都写在了 Activity / Fragment 中。
这会导致什么结果:
Activity / Fragment 代码臃肿,逻辑混乱
难维护,难复用
举一个代码例子,我们要在冰箱中放一个苹果,那么我们代码会这样写:
class Fridge {
val apple = Apple() // 创建一个苹果
fun store() {
storeAnApple(apple) // 存放苹果
}
}
这样写有没有问题?如果你觉得没有问题,那我的文章你应该继续往下读,如果觉得有问题,那你可以跳过这整节了。
Fridge
是冰箱类,那么按照 单一职责原则
,它的作用应该是存储物品。但是在代码中,它却做了一个事情:那就是将苹果创建出来了。
冰箱类,它不应该知道苹果是如何产生的,它只需要拿到苹果并存储就行了。不然的话,冰箱要存储香蕉,那岂不是又new出一个香蕉,要放水果蔬菜,又要new出水果蔬菜…
显然,我们不需要 Fridge 来创建 Apple 对象,所以我们需要外部来帮我创建。比如苹果工厂。
或者我们使用 依赖注入框架 Dagger2,通过类似下面的代码:
class F