Dagger2,仅仅是dagger2
经过事实证明,凡事涉及到依赖注入的框架,就没有简单的。学习的过程也会是一波三折。
每每想到看官方文档,英语是硬伤。
当满怀感激看到有大神贴出文章以及使用教程,仔细研读又发现越来越迷糊。试想一下也对,大神都是踏坑一路走来的,也许对大神们来说,坑已经不叫坑了,面对着他们眼中的小圆洞,我是欲哭无泪。
再有很多人说到Dagger2和现在比较流行的框架MVP是绝配,而且代码示例也是Dagger2+MVP(恨不得这俩框架生生世世在一起),更不要说另外有些大神又加了一些神级框架RXjava、retrofit等等,面对着铺天盖地的注解以及陌生方法,我只想说:我就想看看Dagger2的示例代码,仅仅是dagger2。
思前想后感觉有必要从一个小白的角度写一个教程。
因为是所学所想,并且本人也是小白,因此不敢涉及太深,仅仅讲一下浅显的知识,让程序跑起来而已,就当认识框架所走的第一步。剩下是跑,是跳,是驻足不前就看各位客官自己了。
首先Dagger2的核心知识点是四大注解
Inject 、 cpmponent 、 moudle 、provides
Inject从字面理解注入、注射,那就不难理解这个注解很重要。
该如何使用,或者说标记在哪里呢?简单说两个部分:
(1)、目标引用的声明部分
@Inject
UserData data;
(2)、需要注入对象的构造方法上
@Inject
public UserData() {
}
这就类似于告诉dagger框架
一个是“这里需要注入对象”
一个是“这里提供注入对象的实例化方法”
现在实例对象的出口定义了,入口也定义了,但是怎么去关联两个“Inject”呢。
这就要说另一个注解了Component。
具体用法:
首先定义一个接口或者是抽象类(非抽象的不可以),然后加上注解@Component
此外需要定义一个抽象方法,
方法名约定俗成为inject
返回值类型为 void
带参数,参数为需要注入实例所在的目标类
事例:
@Component
public interface GetUserComponent {
void inject(GetUserData getUserData);
}
其实做完上面两部,依赖注入的准备工作就可以完成了,
只需要在注入实例的目标类的初始化方法上声明一下就可以。
方法如下:
public GetUserData(){
DaggerGetUserComponent.builder()
.build()
.inject(this);
}
说明:这是一个构造方法,把声明写在了构造方法里面(其实可以用静态代码块(代码块)的方式试一下)
这样轻轻松松完成依赖注入,简单快捷。
前文总结:其实很多人做到这里开始碰到坎了,--“DaggerGetUserComponent这个东西是个什么鬼,没印象啊,楼主你坑我,你偷偷的把最重要的东西丢下没写。”好吧,其实不是我没写,这个类是apt自动生成的,当写完一个xxxComponent,可以编译一下,在apt中就会生成一个DaggerXxxComponent,就会有上面的初始化方法了,同时注意一下,还记得接口里写的那个inject嘛,apt自动重写inject方法。(一个新手常跳的坑被填了)
讲到这里还不算完,开头说过有四个基本点,还有两个呢……
下面细细道来:
剩下的是Module 和 Provides
明明已经可以注入了为什么还要有这个呢,具体什么时候用呢---
可以试想一下,在我们自定义类的时候我们可以随意修改随便注解,但是如果我们引用第三方的类,那该怎么办呢,拿到源代码,然后修改,最后编译?天……
这个时候就可以使用Module,这样就可以通过该类创建三方对象实例,然后注入到目标对象中
用法:
创建一个类,标注@Module,然后定义一个可以返回注入实例对象类型的方法标注@Provides,事例:
@Module
public class MainModule {
@Provides
public GetUserData provideUserData(){
return new GetUserData();
}
}
仅仅这样还是不够的,还需要告诉component,让他来这里找实例化对象
这样就需要修改一下component,其实就是在注解上添加参数具体代码如下:
@Component(modules = MainModule.class)
public interface MainComponent {
void inject(MainActivity activity);
}
因为在注解上加了参数,因此在声明的时候链式调用也需要修改一下
DaggerMainComponent.builder()
.mainModule(new MainModule())
.build()
.inject(this);
这样第三方的依赖注入问题也可以解决了
不管自定义类,还是第三方类,依赖注入没毛病。
有人也许会问:第三方用的那个Module注解,如果是自定义类可以使用嘛?
其实没问题,不管第三方还是自定义都可以通过写Module进行初始化。
那又有人问了,这两种初始化实例对象方式有什么区别嘛?
有区别的,在dagger2中,框架会优先从Module中寻找实例化对象,如果找到了,就会获取对象,停止寻找,如果没找到,那就再去通过inject的方式进行实例化对象。换句话说Module的优先级比较高。
至此,dagger2的入门工作也就讲到这里。
本次帖子相关代码奉上
这两天看了很多的帖子,确实启发很大,没有他们的讲解,我这个帖子也不会出现,特此感谢。