依赖注入框架
依赖注入框架
在我们开发的过程中,我们会遇到一些依赖注入框架,所以总结一下:
Dagger2、koin、Hilt。其中现在用的多的是koin和Dagger2。但是由于Dagger2上手有难度,所以官方推出了Jetpack Hilt来代替Dagger2,所以现在主修koin和Hilt是可以的。
什么是依赖注入?为什么要依赖注入?
首先要明确什么是依赖?对Android而言,这只是一个名词,具体一点就是一个类的里面变量就是类的依赖,就称为类依赖于变量。所谓依赖注入就是内部的类的变量不由开发者来定义,而是由外部去引入注入。
依赖注入可以自动加载依赖,使用一个模块但不依赖这个模块的具体实现。并且实现了一个数据共享的一个机制。如果不需要共享的数据使用依赖注入可以使它更加的简洁,在加载的过程中可以免去初始化加载的过程,提高效率。
怎么进行依赖注入?
Hilt
Dagger2
Dagger2是一个依赖注入框架,官方维护的一个依赖注入框架。
https://github.com/google/dagger/releases
依赖注入是指所需要的事物是由注入来取代依赖。
在这里将依赖由注入传递给调用方。这里的依赖是一个变量,调用方是对象和类(PS:变量只是一个名称,对象是已经开辟了内存的地方。类似于人与人名的关系)
- 项目中多个模块会用到一些公共实例。
- 这些公共实例应该是单例对象。
其实我们所使用的依赖注入已经很多,类似于这样:
1 | class edge{ |
就是构造器来实现依赖注入,当调用构造函数的时候,就有一个对象被创造出来,将这个变量去注入了这个对象。
这是一个简单的依赖注入,我们还有setter方法,接口注入,依赖注入框架实现。
依赖注入的目的是为了解耦和便于维护,如果我使用依赖的方式来进行创建:
1 | interface Energy { |
类car会有多于的责任,负责这个energy对象的创建。如果我们想修改这个汽车的能源,那么必须修改这个汽车类。但是汽车使用哪种能源应该是由汽车制造商来决定,而不是由汽车决定。这就造成了耦合性高和维护不方便的麻烦。所以我们经常在多人协作项目的时候采用第三方的依赖注入框架,便于维护和解耦(控制反转的设计模式)
看了一篇博客中对依赖注入描述的一句话:Dependency injection (DI) is the concept in which objects get other required objects from outside.
- 添加依赖(具体版本号见上述Github地址)
1 | dependencies { |
使用注解(annotations)
- @Moudle and @Provides:定义提供依赖的类和方法(Moudle注解在一个类上,Provides注解在一个方法上)
- @Inject:使用在方法、构造器等请求依赖项的地方
- @Component:执行依赖注入(通常在一个接口中使用)编译后会产生相应的Dagger类,这个类提供了依赖方和所需依赖方的桥梁。
(注:dagger2不允许在私有域中使用)
注入过程
1
2
3
4
5
6
7
8
9
10
11// Definition of the Application graph
public interface ApplicationComponent {
}
// appComponent lives in the Application class to share its lifecycle
public class MyApplication extends Application {
// Reference to the application graph that is used across the whole app
ApplicationComponent appComponent = DaggerApplicationComponent.create();
}
对于上述,只是去在类中注入一个依赖,所以可以直接利用create()来完成这个事情。
对于一个Activity就是利用Inject来注入。
@Inject 做的是将依赖对象注入到目标中,@Module 提供依赖对象(参数)。它们两个之间的联系谁来搭建呢? @Component就出现了
如果对于Activity来注入:
- 先找到需要注解的位置:
1 | public class MainActivity extends AppCompatActivity { |
这个注释是一定要在onCreate方法之前去注解@inject,因为在这个方法中会实现避免出现 Fragment 恢复问题。在 super.onCreate() 的恢复阶段,Activity 会附加可能需要访问 Activity 绑定的 Fragment。
在第一步结束以后,我们的MainActivity就持有了MainPresenter的引用,Mainpresenter被依赖。
- 为注入的实例化提供参数(@Module)
1 |
|
返回值很重要,这样就说清楚了提供的参数
- 搭建桥梁(@Component)
这个Componet的作用就是告知Dagger需要注入依赖的对象,例如:
1 |
|
注意:如果要注入的为两个参数,应该是两种inject方法而不是一种通用方法。
1 |
|
如果开发不同的Activity,那么我们就可以改变modules=… .class 和改变Inject的参数来进行改变。
做完了Component时,我们必须去ReBulid一下项目,这样才能生成我们需要的DaggerXXX类
4.编写注入代码
1 | public class MainActivity extends AppCompatActivity { |