【相关链接】
(1)https://blog.csdn.net/shusheng0007/article/details/80950117
(2)https://www.jianshu.com/p/2cd491f0da01
(3)https://www.jianshu.com/p/5f11cacb6250
(4)http://www.jcodecraeer.com/a/anzhuokaifa/2018/0307/9471.html
【1】dagger2概念
【总结】主要是通过Java注解(Annotation)来工作。

【通俗】是一个依赖注入框架,butterknife也是一个依赖注入框架。不过butterknife,最多叫奶油刀,Dagger2被叫做利器啊,他的主要作用,就是对象的管理,其目的是为了降低程序耦合。

【2】什么是依赖注入
依赖注入是一种给一个对象提供其依赖的对象的技术。例如A对象需要依赖B对象,那么此处关键点就是不能在A里面去new B对象,必须通过某种方式将B对象提供给(注入)A中,例如最简单的方式是通过一个 set(B b)方法
【3】使用依赖注入和不使用依赖注入有什么区别呢?
【答案】其最主要的目的就是为了解耦,随即而来的就是可测试性,可维护,可扩展性就大大提高了。
【4】dagger2中最重要的就是Inject,Component,Module。
(A) Inject

【注释】
(1)在A类中标记B类的字段:告诉dagger 我们要注入B类的实例到A类中,你帮我搞定(我王二狗要牛翠花,dagger2你帮我搞定)。
(2)在B类中标记B类的构造函数:告诉dagger B类是一个可以被注入的类,如果你想把B的实例对象注入到其他类中,例如注入到A类中,是没有任何问题的。
(B) Component
(1) 代码
@Component(modules = {DaggerModule.class})
public interface MatchComponent
{
void mainActivityInject(MainActivity activity);
}
(2)注释
Component 一般是一个使用 @Component标记的接口,其持有A类的实例,其在A类中发现有使用@Inject标记的属性b,就会去查找这个属性的类型B,然后调用其构造函数产生实例对象赋值给b。这样就完成了对A类中b属性的赋值,即完成了依赖注入。
(C)Module
C类是一个没有使用@Inject注解其构造函数的类,而且我们也无法加上,可能由于它是一个第三方类,或者其他原因。那我们想要使用dagger2将其注入到A类中就需要使用到Module。Module负责提供C类的实例对象,当Component发现了使用 @Inject注解的C类属性时,先去Module中查找,没有的话再去看其构造函数是不是使用@Inject标记了,如果都没有,注入失败。
【总结】Dagger 是通过@Inject使用具体的某个对象,这个对象呢,是由@Provides注解提供,但是呢,这个@Provides只能在固定的模块中,也就是@Module注解,我们查找的时候,不是直接去找模块,而是去找@Component。
【示意图】

我们反向推到,当们使用
@Inject
A a
想要获取a对象的示例的时候,Dagger2 会先去找,当前Activity或者Fragment所连接的桥梁,例如上图中,连接的只有一个桥梁,实际上可以有多个,这个桥梁,会去寻找他所依赖的模块,如图中,依赖了模块A,和模块B,然后在模块中,会去寻找@Providers注解,去寻找A的实例化对象。
【集成】

【1】依赖:
compile 'com.google.dagger:dagger:2.11'
annotationProcessor 'com.google.dagger:dagger-compiler:2.11'
【2】开发步骤:
(1) 创建Moudule
// 第一步 添加@Module 注解
@Module
public class MainModule {
// todo
}
(2)创建具体的示例:
// 第一步 添加@Module 注解
@Module
public class MainModule {
//第二步 使用Provider 注解 实例化对象
@Provides
A providerA() {
return new A();
}
}
(3)创建一个Component接口:
//第一步 添加@Component
//第二步 添加module
@Component(modules = {MainModule.class})
public interface MainComponent {
//第三步 写一个方法 绑定Activity /Fragment
void inject(MainActivity activity);
}
(4)Rebuild Project

然后AS 会自动帮我们生成一个:

(5)将Component与Activity/Fragment绑定关系:
public class MainActivity extends AppCompatActivity {
/***
* 第二步 使用Inject 注解,获取到A 对象的实例
*/
@Inject
A a;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/***
* 第一步 添加依赖关系
*/
//第一种方式
DaggerMainConponent.create().inject(this);
//第二种方式
DaggerMainConponent.builder().build().inject(this);
/***
* 第三步 调用A 对象的方法
*/
a.eat();
}
}
【高级用法】
(1)构造方法需要其他参数时候:

(2) 模块之间的依赖关系:


这样的话,Dagger会现在A moudule 中寻找对象,如果没找到,会去找module B 中是否有被Inject注解的对象,如果还是没有,那么GG,抛出异常。
(3)一个Component 应用多个 module:

(4)dependencies 依赖其他Component:

(5) @Named注解使用:


(6)@Singleton注解:单例模式,是不是超级方便,你想然哪个对象单利化,直接在他的Provider上添加@Singleton 就行了。


【思考】那有人就要问了,没什么办法么,我就想全局只要一个实例化对象啊? 办法肯定是有的。
(7)自定义Scoped:

【总结】

(8)lazy 和 Provider

其中Lazy(懒加载)的作用好比component初始化了一个present对象,然后放到一个池子里,需要的时候就get它,所以你每次get的时候拿到的对象都是同一个;并且当你第一次去get时,它才会去初始化这个实例。
provider(强制加载)的作用:
1:同上当你第一次去get时,它才会去初始化这个实例
2:后面当你去get这个实例时,是否为同一个,取决于他Module里实现的方式
(9)Subcomponent: 当使用Subcomponent,那么默认会依赖Component


【架构1】 MVP + Dagger2




【架构2】MVVM+Retrofit+Dagger2
【扩展】

【解答】http://www.jcodecraeer.com/a/anzhuokaifa/2018/0307/9471.html
网友评论