一、Dagger2是什么?
Dagger是程序在编译时进行依赖注入的框架,原来是由Square公司维护,现在由Google维护。我们可以把它当做应用中的一个模块, 负责为其它模块提供实例并且注入依赖关系。Dagger Leiva说,特别适合用在低端设备上,因为它没有采取反射而使用了预编译技术,因为基于反射的DI非常占用资源和耗时。Dagger或许不是最理想的依赖注入框架,它是最高效的。这里我们简单介绍一下Dagger。
Paste_Image.png二、使用Dagger2有什么好处?
我们在activity中有可能会用到很多很多的类,这些类要在activity中进行实例化,这样就导致我们的activity非常依赖这么多的类,这样的程序耦合非常严重,不便于维护和扩展。Dagger就是用来创造这个容器,所有需要被依赖的对象在Dagger的容器中实例化,并通过Dagger注入到合适的地方,实现解耦,MVP框架就是为解耦而生,因此MVP和Dagger是绝配;
三、什么是依赖?
在介绍Dagger 之前,我们先说一下什么依赖以及什么是依赖注入?在 Class A 中,有 Class B 的实例,则称 Class A 对 Class B 有一个依赖。例如下面类 Human 中用到一个 Father 对象,我们就说类 Human 对类 Father 有一个依赖,如下:
public class Human {
...
Father father;
...
public Human() {
father = new Father();
}
}
四、什么是依赖注入?
依赖注入就是非自己主动初始化依赖,而通过外部来传入依赖的方式,简单来说就是不使用 new 来创建依赖对象。使用 Dagger2 创建依赖对象,我们就不用手动初始化了。个人认为 Dagger2 和 MVP 架构是比较不错的搭配,Activity 依赖的 Presenter 可以使用该DI框架直接生成,实现解耦,简单的使用方式如下:
public class MainActivity extends BaseActivity {
@Inject
MainActivityPresenter presenter;
...
}
若您还是对依赖注入不了解,点击我可以让您了解更多
,dagger2中核心点就是java注解,点击我可以了解更多java注解知识
五、什么是JSR-330?
为了最大程度的提高代码的复用性、测试性和维护性,java的依赖注入为注入类中的使用定义了一整套注解(和接口)标准。Dagger1和Dagger2(还有Guice)都是基于这套标准,给程序带来了稳定性和标准的依赖注入方法。
六、Dagger的发展历程?
Dagger的发展历程由Dagger1到Dagger2。下面简单介绍一下两个版本的区别:
1. Dagger1
这个版本不是这篇文章的重点,所以我只是简略地说一下。不管怎样,Dagger1还是做了很多的贡献,可以说是如今Android上最流行的依赖注入框架。它是由Square公司受到Guice启发创建的。
基本特点:
多个注入点:依赖,通过injected
多种绑定方法:依赖,通过provided
多个modules:实现某种功能的绑定集合
多个对象图: 实现一个范围的modules集合
Dagger1是在编译的时候实行绑定,不过也用到了反射机制。但这个反射不是用来实例化对象的,而是用于图的构成。Dagger会在运行的时候去检测是否一切都正常工作,所以使用的时候会付出一些代价:偶尔会无效和调试困难。
2. Dagger2
Dagger2是Dagger1的分支,由谷歌公司接手开发,目前的版本是2.0。Dagger2是受到AutoValue项目的启发。 刚开始,Dagger2解决问题的基本思想是:利用生成和写的代码混合达到看似所有的产生和提供依赖的代码都是手写的样子。
如果我们将Dagger2和1比较,他们两个在很多方面都非常相似,但也有很重要的区别,如下:
再也没有使用反射:图的验证、配置和预先设置都在编译的时候执行。
容易调试和可跟踪:完全具体地调用提供和创建的堆栈
更好的性能:谷歌声称他们提高了13%的处理性能
代码混淆:使用派遣方法,就如同自己写的代码一样
当然所有这些很棒的特点都需要付出一个代价,那就是缺乏灵活性,例如:Dagger2没用反射所以没有动态机制。
六、Dagger2的主要方法以及相关介绍?
Dagger2主要的注解有:@Inject、@Module 、@Component 、@Provides 、@Scope 、@SubComponent 等。
1. @Inject:
通常在需要依赖的地方使用这个注解。换句话说,你用它告诉Dagger这个类或者字段需要依赖注入。这样,Dagger就会构造一个这个类的实例并满足他们的依赖。
2. @Module:
Modules类里面的方法专门提供依赖,所以我们定义一个类,用@Module注解,这样Dagger在构造类的实例的时候,就知道从哪里去找到需要的 依赖。modules的一个重要特征是它们设计为分区并组合在一起(比如说,在我们的app中可以有多个组成在一起的modules)。
3. @Provides:
在modules中,我们定义的方法是用这个注解,以此来告诉Dagger我们想要构造对象并提供这些依赖。
4. @Component:
Components从根本上来说就是一个注入器,也可以说是@Inject和@Module的桥梁,它的主要作用就是连接这两个部分。 Components可以提供所有定义了的类型的实例,比如:我们必须用@Component注解一个接口然后列出所有的 @Modules组成该组件,如 果缺失了任何一块都会在编译的时候报错。所有的组件都可以通过它的modules知道依赖的范围。
Component会查找目标类中用Inject注解标注的属性,查找到相应的属性后会接着查找该属性对应的用Inject标注的构造函数(这时候就发生联系了),剩下的工作就是初始化该属性的实例并把实例进行赋值。因此我们也可以给Component叫另外一个名字注入器(Injector)
Paste_Image.pngModule应该是属于Component的实例端的(连接各种目标类依赖实例的端),Component的新职责就是管理好Module,Component中的modules属性可以把Module加入Component,modules可以加入多个Module。
Paste_Image.png Paste_Image.png5. @Scope:
Scopes可是非常的有用,Dagger2可以通过自定义注解限定注解作用域。后面会演示一个例子,这是一个非常强大的特点,因为就如前面说的一样,没必要让每个对象都去了解如何管理他们的实例。
七、Dagger2的使用详解?
1. 添加依赖
android-apt, 提供dagger2使用编译生成类的功能。具体作用请看http://blog.csdn.net/zjbpku/article/details/22976291。
retrolambda, 提供Lambda表达式支持的功能。
apply plugin: 'com.android.application'
apply plugin: 'com.neenbedankt.android-apt'//添加这里
android {
...
// 使用Java1.8
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8//添加这里
//targetCompatibility JavaVersion.VERSION_1_8
}
}
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'//添加这里
}
}
dependencies {
compile 'com.google.dagger:dagger:2.9'//添加这里
apt 'com.google.dagger:dagger-compiler:2.9'//添加这里
...
}
由于工作关系这里Dagger2上篇先写到这里,后续继续补充下篇详解。
网友评论
dependencies {
compile 'com.google.dagger:dagger:2.11'
annotationProcessor 'com.google.dagger:dagger-compiler:2.11'
}
就可以使用了。