Dagger2从基础到高级

github地址
文档

一、为什么要学习Dagger2

第一次看Dagger2时,只知道它是一个依赖注入框架,能够让RxJava+Retrofit+MVP+Dagger2这种架构更好的解耦,对于怎么解耦还是一脸懵逼。

简单来说,依赖注入就是为了控制反转和解耦的,这些高深的名词儿可能一时也不懂。可以举个例子:

假设做一个用户注册的功能,依赖关系如图:

UserStore可以把用户数据存到本地,ApiService可以将用户数据存到服务端,UserManager包含这两个类
这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

好像看似没什么问题
当我们将用户数据保存到本地SharedPrefrence中,此时需要上下文对象:

这里写图片描述

之后我们就需要改变UserManager这个类:

这里写图片描述

之后还需要改变MainActivity中实例化UserManager,还需要传入Context
这样一来,耦合度是不是特别高,牵一发而动全一身,Dagger2的出现其实就是解决类似的new出来的对象而产生的高耦合的情况。
对于上面的情况,可以这样改动代码较低耦合度:

这里写图片描述
这样改动的话确实可以降低耦合度,但是任然要改动MainActivity中的代码

二、Dagger2的基本使用

集成Dagger2

project的build.gradle添加
dependencies {
… // 其他classpath
classpath ‘com.neenbedankt.gradle.plugins:android-apt:1.8’ //添加apt命令
}
这里写图片描述
module的build.gradle添加
// 添加其他插件
apply plugin: ‘com.neenbedankt.android-apt’//添加apt命令
dependencies {
apt ‘com.google.dagger:dagger-compiler:2.0.2’ //指定注解处理器
compile ‘com.google.dagger:dagger:2.0.2’ //dagger公用api
provided ‘org.glassfish:javax.annotation:10.0-b28’ //添加android缺失的部分javax注解
}
这里写图片描述

必不可少的三种元素:

(可以理解Container就是自己,Component就是提供服务的中间商,Module就是提供服务的……….老司机都懂)

Module:提供依赖的集合
Component:连接Mudle和Container,注入器
Container:容器(需要通过注入来实现创建对象)
这里写图片描述

注解:

@Inject:

通常在需要依赖的地方使用这个注解。换句话说,你用它告诉Dagger这个类或者字段需要依赖注入。这样,Dagger就会构造一个这个类的实例并满足他们的依赖。

@Module:

Modules类里面的方法专门提供依赖,所以我们定义一个类,用@Module注解,这样Dagger在构造类的实例
时候,就知道从哪里去找到需要的 依赖。modules的一个重要特征是它们设计为分区并组合在一起(比如说,
我们的app中可以有多个组成在一起的modules)

@Provide:

在modules中,我们定义的方法是用这个注解,以此来告诉Dagger我们想要构造对象并提供这些依赖。

@Component:

Components从根本上来说就是一个注入器,也可以说是@Inject和@Module的桥梁,它的主要作用就是连接这两个部分。 Components可以提供所有定义了的类型的实例,比如:我们必须用@Component注解一个接口然后列出所有的

还是使用第一部分的代码用(Dagger2来改造):
为了简化,假设将用户数据只保存到服务端,只用类ApiService

在需要注入的字段上加@Inject注解,以此来告诉Dagger2这个字段需要依赖注入,此时就不需要new对象了。

这里写图片描述

Dagger2会帮我们去Component里面找这个类的实例,所以我们需要定义一个Component接口,注意Component必须是接口:

这里写图片描述
或者传入多个Module这里写图片描述

使用@Component注解时,需要关联一个Module,所以我们接下来再创建一个Module类(真正创建mService对象的地方):

需要使用@Module和@Provide注解
这里写图片描述

通过上面的代码,可以看出,Module是提供依赖的,Activity是使用依赖的,Component起到桥梁的作用

继续补充代码。。。。。
可以看到上面Component通过@Component注解和UserModule进行了关联,但是怎样和Container(Activity)进行关联呢?

这里写图片描述

添加了这一句代码可以关联MainActivity,但是这样在MainActivity中使用@Inject来注入实例对像还是不行,因为当我们创建好Component的时候,通过编译(需要Rebuilde),Dagger2会帮我们生成DaggerUserComponent这个类(Dagger是前缀,UserComponent是我们创建的接口Component)

这里写图片描述

我们可以使用如下方法来实现注入的目的

这里写图片描述

我们可以在ApiService类中register()方法中打印,看看是否注入成功

再来看一些复杂点的例子
我们在需要依赖注入的对象,在构造时需要传入参数,此时怎么办呢?
我们只需要在Module里面再定义一个方法,创建该对象并返回,此时需要传入参数

这里写图片描述
我们这时为了方便说明问题,UserManager的构造方法只传一个ApiService对象,不考虑UserStore
这里写图片描述

如果我们这么写,然后在MainActivity中调用会不会成功呢?答案肯定是不成功的

会报以下错误
这里写图片描述
出现这种错误的原因是,在Module中,无法提供ApiService对象,那么我们怎么做呢?

有两种方式去提供对象

第一种方式:
在Module中写一个方法提供ApiService对象
这里写图片描述

第二种方式
通过ApiService的构造方法提供,构造方法上添加@Inject注解,如果Module中没有提供第一种方式的方法,Dagger2会自动去找ApiService带有@Inject的构造方法,只能有一个构造方法带有@Inject
这里写图片描述

如果ApiService中还有其他的带参数的构造方法添加了@Inject,那么还必须在Module中提供返回参数类型的方法
这里写图片描述

发现会直接报错,要求提供一个String类型的参数
所以还要我们在Module里面再提供一个方法返回类型的参数
这里写图片描述

通过以上的学习相信大家应该对Dagger2有了基本的了解所以废话不多说,继续。。。。。

上面的代码只是用了Usermanager(ApiService service)这个构造方法,那么下面我们再使用Usermanager(UserStore store , ApiService service)这个构造方法
ApiService 对象的提供上面我们已经写好了,现在提供 UserStore 对象

同样我们在Module中添加方法

这里写图片描述

此时需要我们传一个Context对象,此时我们该如何是好呢?

我们可以利用Module的构造方法来传入Context对象
在module中添加构造方法

这里写图片描述

此时并不能使用,然后我们在MainActivity中利用DaggerUserManager的第二种方式创建依赖

这里写图片描述

此时我们已经掌握了Dagger2的最基本用法

关于Dagger2的其他用法,在下一篇将会讲述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值