声明:第一次做笔记,仅做自己学习后总结记录,如有侵权请及时联系我删除.
笔记只作用法记录,不涉及原理,如果有人看过本文,发现错误,请留言指出.谢谢
笔记代码: https://github.com/oneway2030/Dagger2Note
参考文章:
https://www.jianshu.com/p/24af4c102f62
https://github.com/luxiaoming/dagger2Demo
https://www.jianshu.com/p/1d84ba23f4d2
文章目录
*@Inject 与 @Component
*@Module与@Provides
*@Name与@Qualifier
* @Scope(作用域)
-@Singleton
-@xxxxx自定义注解
* @dependence与@SubComponent
* set与map
* Lazy(懒加载)
零. 简单使用 @Inject 与 @Component
举个栗子: 在mianactivity中使用某个对象(Test)
1.在test构造上加入@Inject 注解
![](https://img.haomeiwen.com/i4380281/9babc3f9725d2c89.png)
2.创建注入器Component接口
![](https://img.haomeiwen.com/i4380281/9e36165df346e033.png)
3.把Test对象注入MainActivity
![](https://img.haomeiwen.com/i4380281/517ec36265b444c7.png)
一. Module与Provides
举个栗子: 在OneActivity中使用使用第三方库的对象(Test2).
因为无法在第三方库上加注解所以这里要使用Module与Provides
1.第三方库Test2对象
![](https://img.haomeiwen.com/i4380281/c3d607b11f0c1703.png)
2.构建Module
![](https://img.haomeiwen.com/i4380281/0178534c40858aca.png)
3.创建注入器Component
注:@Component(modules = OneModule.class) 指明该Component依赖OneModule
如果该Component依赖多个module则:
@Component(modules = {OneModule.class,xxxx.class,xxxx.class.....})
![](https://img.haomeiwen.com/i4380281/5f0e2a72aa8caa4a.png)
4.创建注入器 将Test2注入到OneActivity
![](https://img.haomeiwen.com/i4380281/184fb3eff9a44fee.png)
* 这里要注意一下, 如果需要注入的Test2是自己写的,可以加入@Inject注解,并且这个Test2构造需要Context参数,那么module这样写
![](https://img.haomeiwen.com/i4380281/8e754fde1f41f2a9.png)
![](https://img.haomeiwen.com/i4380281/336d29eab5af72cb.png)
OneActivityComponent与OneActivity不变.
二. @Name与@Qualifier
举个栗子: 假设孩子分为男孩女孩, 那么modul里提供两个
函数制造两种孩子,然后注入到TwoActivity中,如图
![](https://img.haomeiwen.com/i4380281/b95135820f73ef4f.png)
![](https://img.haomeiwen.com/i4380281/8ed5019cea9c4c11.png)
![](https://img.haomeiwen.com/i4380281/f002f41b7e469f3f.png)
这种直接编译报错,dagger2无法分辨你注入的是哪一个性别的孩子.
会报错:cannot be provided without an @Provides- or @Produces-annotated method.
正确做法:
方式一:@Name
1.在module中 提供孩子的函数上加入标签@Name,那么的名字随意,但是后面使用中要与这里保持一致
![](https://img.haomeiwen.com/i4380281/c7689c331eeb5a02.png)
2.在注入的地方也加入@Name注解, 注解里的String与Module里保持一致
![](https://img.haomeiwen.com/i4380281/e41655f7deb1ef99.png)
方式二:@Qualifier
1.自定义Qualifier 注解
![](https://img.haomeiwen.com/i4380281/d7b3ceab326044eb.png)
![](https://img.haomeiwen.com/i4380281/a61af76827f9251c.png)
2.在module中 加上@你定义相对应的注解名字
![](https://img.haomeiwen.com/i4380281/01d652d70aeb81f2.png)
3.在注入的时候 也加上@你定义相对应的注解名字
![](https://img.haomeiwen.com/i4380281/2a4c1387c9cdec37.png)
三 Scope(作用域)
两个要点:1.关键注解 @Singleton 2.自定义注解@XXXX
1. @Singleton 单例
先说使用:
![](https://img.haomeiwen.com/i4380281/2ab72d4a53f91147.png)
1.步骤一 在module里Provide方法上添加@Singleton注解
![](https://img.haomeiwen.com/i4380281/5922956bd931a25b.png)
2.步骤二 在Component上加@Singleton注解
![](https://img.haomeiwen.com/i4380281/6f6c345b1b96d411.png)
那么就已经完成
![](https://img.haomeiwen.com/i4380281/de6805b39e6c8825.png)
打印结果:
![](https://img.haomeiwen.com/i4380281/3696958e00d0117e.png)
![](https://img.haomeiwen.com/i4380281/34a32911534457ed.png)
两个个地址相同,那么完成了单例.
注:@Singleton单例并不是全局单例,可以理解为局部单例.
举个栗子:跳转到第二个界面SecondActivity,再次注入 Test3,这个时候会发现,打印出的one和two也相同, 但是与ThreeActivity的地址不相同.(这里就不贴代码了,自己有兴趣就去试试.)
为什么呢?
我的理解是:SecondActivity重新生成了注入器Component,
@Singleton只能保证同一个注入器所在的作用域是单例.
那么怎么实现全局单例呢?只要保证Component唯一,也就全局单例了.So...只要把Component写在Application里,然后全局使用同一个Component,也就实现了全局单例.
![](https://img.haomeiwen.com/i4380281/b30c770f476b098a.png)
2. 自定义作用域
1.步骤一自定义注解在注解上@Scope
![](https://img.haomeiwen.com/i4380281/92671d8eb862b9fc.png)
2.把方法一种的@Singleton 换成@ThreeActivityScppe (@你定义的注解名字)
然后使用就一模一样.
此方法适用场景:A,B界面共用数据C, AA,BB界面公用数据D,那么A,B界面使用一个自定义注解的作用域@CScope,AA,BB公用另一个自定义作用域@DScope
四. 组件依赖 dependence与SubComponent
方式一 dependence:
![](https://img.haomeiwen.com/i4380281/faba0a9f4a055a42.png)
步骤一:有一个通用的Component 并提供两个函数
![](https://img.haomeiwen.com/i4380281/5b114cd6dcbf0dec.png)
![](https://img.haomeiwen.com/i4380281/04701ef426dab2d0.png)
步骤二:让FourActivityComponent依赖这个CommonComponent
![](https://img.haomeiwen.com/i4380281/4a2ec62c2cc7310b.png)
![](https://img.haomeiwen.com/i4380281/6235b7ea0722d594.png)
步骤三: 注入
![](https://img.haomeiwen.com/i4380281/dfad0e40915cb6eb.png)
打印结果
![](https://img.haomeiwen.com/i4380281/5709d66752b8e479.png)
方式二 SubComponent:(此方式不是太理解)
步骤一:定义module
![](https://img.haomeiwen.com/i4380281/c94873e244edfd4d.png)
![](https://img.haomeiwen.com/i4380281/7a0c7155aaef5114.png)
步骤二 定义component
![](https://img.haomeiwen.com/i4380281/5585790d4a92cfbd.png)
![](https://img.haomeiwen.com/i4380281/9f1ef795c1a32207.png)
![](https://img.haomeiwen.com/i4380281/dc0c0936e720f1f6.png)
步骤三:注入
![](https://img.haomeiwen.com/i4380281/e51c44406cbd56ec.png)
五. set与map
1.map
![](https://img.haomeiwen.com/i4380281/f0ca276d24f588e4.png)
2.set
![](https://img.haomeiwen.com/i4380281/84603561e6b43094.png)
注入:
![](https://img.haomeiwen.com/i4380281/97ad9d9ec985771b.png)
打印结果
![](https://img.haomeiwen.com/i4380281/0f50a77b91c3339f.png)
![](https://img.haomeiwen.com/i4380281/f55bfed2497fb495.png)
六. 懒加载
使用Lazy包裹被注入的对象, 在使用的时候调用get()函数
![](https://img.haomeiwen.com/i4380281/9507cb36e799e435.png)
![](https://img.haomeiwen.com/i4380281/b5935ad263ef5f8c.png)
网友评论