为了介绍Dagger2的使用,我们搭建了一个Demo来逐步分析,大家可以在这里 下载源码(https://github.com/dushaofeng/DaggerDemo.git)。
        上一节我们介绍了 《Dagger2教程一之配置(原)》,这一节我们来介绍Dagger2的具体使用方法。

一、原始方式

我们先来看一下如果不使用Dagger的情况,我们在Activity中创建一个Bean的对象,其构造方法无需传递任何参数,但是内部会初始化其成员name,然后在Activity中使用该对象。

Bean的内容为:

        public class Bean {private String mName = null;public Bean() {this.mName = "原始方式";}public String getName() {return mName;}}

在Activity中创建并使用该对象:

        private void testOrignal() {Bean bean = new Bean();Log.d(TAG, "不使用Dagger时 Name:" + bean.getName());}

其结果如下图所示:
        

二、最简单的Dagger使用方式

接下来我们通过一个例子来介绍如何通过Dagger来实现上面的代码。

2.1、改造Bean

和Bean类似,我们新建一个BeanForDagger的对象,其内容为:

        public class BeanForDagger {private String mName = null;@Injectpublic BeanForDagger() {this.mName = "Dagger方式";}public String getName() {return mName;}}

这个BeanForDagger和Bean的区别有两点:
        1、mName的初始化名称不同,这是为了区分两个对象

2、BeanForDagger的构造方法多了@Inject的注释,它会告诉Dagger用这个方法来注入目标类

2.2、创建Component文件

然后我们我们新建一个BeanComponent的接口(文件),其内容如下:

        @Componentpublic interface BeanComponent {void inject(MainActivity activity);}

请注意,这个接口使用了@Component的注释。

2.3、使用Dagger

经过上面修改之后,我们就可以使用Dagger来自动创建BeanForDagger对象了。
        首先在Activity中声明该变量:

        @InjectBeanForDagger mBeanForDagger;

然后我们可以这样使用该变量:

        private void testDagger() {// 触发Dagger机制DaggerBeanComponent.create().inject(this);if (mBeanForDagger != null) {Log.d(TAG, "使用Dagger注入变量,mBeanForDagger Name:" + mBeanForDagger.getName());}}

运行之后的Log如下:
        
        这说明我们已经可以使用mBeanForDagger了,但是请注意,在Activity中(以及BeanComponent或BeanForDagger中),我们并没有创建(new)BeanForDagger的对象。

也就是说,Dagger帮助我们完成了创建BeanForDagger对象的工作

2.4、Dagger创建对象的过程

这一节我们通过最简单的描述来简单介绍一下Dagger是如何帮助我们创建BeanForDagger对象的。
        首先,在Activity的testDagger方法中,多了这么一句:

            DaggerBeanComponent.create().inject(this);

而这里的DaggerBeanComponent是Dagger根据BeanComponent自动生成的, 每一个XXXComponent都会生成对应的DaggerXXXComponent文件
        当调用inject()时,DaggerBeanComponent就会扫描inject方法中的参数(当前就是Activity)中 用@Inject标记的变量,对于当前的Activity来说,只有mBeanForDagger变量被标记。
        找到这个需要被注入的变量后,发现他的类型是BeanForDagger,接下来,Dagger就会去搜索BeanForDagger的类,然后找到该类中 用@Inject标记的构造方法,并用该构造方法来创建对象。
        这个过程简单来说就是这个步骤:
        1、通过DaggerXXXComponent的Inject()触发注入过程
        2、搜索目标类中用@Inject标识的需要注入的对象

3、找到需要注入对象后,寻找该对象中用@Inject标识的构造方法,完成自动创建过程

2.5、用到的注释

截至目前,我们用到了两个注释: @Inject和@Component,其中的Inject用来注释需要注入的目标对象,以及用来注入的构造方法,而Component用来触发注入机制。

三、带参数的构造方法

上面的使用过程虽然简单,但是他的特点很明显: 需要被注入的对象的构造方法无需传参数!
        因为无需传参,所以Dagger找到该构造方法后可以使用new BeanForDagger()的方法来完成创建工作。
        那么疑问就来了,如果这个构造方法需要参数时,怎么办?Dagger是否具有创建参数的能力?
        比如我们的BeanForDagger对象的构造方法是这样的:

        @Injectpublic BeanForDagger(ParamForDagger param) {this.mName = param.mParamName;}

那么Dagger如何才能获得ParamForDagger的参数呢?
        解决的方法很简单,只需要 在ParamForDagger的构造方法中标记@Inject即可,如这样:

        public class ParamForDagger {String mParamName = null;@Injectpublic ParamForDagger() {mParamName = "ParamName";}}

这样一来,当Dagger在创建BeanForDagger时发现其构造方法需要ParamForDagger的对象,那么Dagger就会 递归查找ParamForDagger类中使用Inject标记的构造方法,找到后,先创建ParamForDagger,然后再用他来创建BeanForDagger。
        也就是说, Dagger具备递归创建对象的能力。
        这个例子执行结果就是,将BeanForDagger中的mName初始化为ParamForDagger中的值:ParamName,运行结果是这样的:
        

四、一个疑问

上面的例子虽然介绍了有参数和无参数的注入,但他们都有两个局限:
        1、需要修改构造方法,添加@Inject的标识,但是对于一些jar包中的方法,或者第三方API中提供的方法, 我们无法修改其源码
        2、虽然构造方法中可以传递参数,但是实际上对这个参数也是有要求的,这个参数虽然会递归创建, 但递归的最后一层的构造方法中还是无法传参的
        要解决这两个问题,请继续看下一篇 《Dagger2教程三之构造方法带参数的情况(原)》

Dagger2教程二之基础使用(原)相关推荐

  1. 区块链教程(二):基础概念介绍

    注:本教程为技术教程,不谈论且不涉及炒作任何数字货币 本系列重点在于以太坊基础知识.以太坊客户端以及以太坊solidity编程,因此博客重点在于以太坊核心知识点的掌握,区块链部分的基础知识可以作为补充 ...

  2. Fugitive.vim 使用教程二

    Fugitive.vim 使用教程二 deran pan, vim-005 原网页:http://vimcasts.org/episodes/fugitive-vim-working-with-the ...

  3. Hive(二)基础教程

    Hive(二)基础教程@你宝爷 一.常用交互命令 #beeline jdbc 启动客户端,可多线程访问,hive不可以 $HIVE_HOME/bin/beeline -u jdbc:hive2://h ...

  4. 计算机java语言教程,计算机JAVA教程二讲Java语言基础知识.doc

    计算机JAVA教程二讲Java语言基础知识 2.1简单数据类型 2.1.1 标识符和保留字 1.标识符 程序员对程序中的各个元素加以命名时使用的命名记号称为标识符(identifier).Java语言 ...

  5. ps文字换行_零基础一周内熟悉使用PS基础工具【Photoshop教程二】

    零基础一周内熟悉使用PS基础工具[Photoshop教程一]这篇的后台数据显示有很多知友都有收藏了.由此可见现在的视频教程,网络上太多太多但,但好多知识都太"碎片化"今天学习这个技 ...

  6. 0基础学原画多久入行?看看你还差什么?

    0基础学原画多久入行?看看你还差什么?许多人认为学习原画的必要因素不是零基础,滴水石穿,基础是历练出来的,学习的自制力也是很重要的,能不能在零基础的情况下学习原画,要看你有没有学习的决心. 学习原画的 ...

  7. [Away 3D] Away3D4.0入门教程(1)--这个世界的基础

    大多数Flash程序员想要接触3D项目的时候,应该都和我一样,最关心的是怎么造一座山,怎么在场景里显示流动的河水,或是怎么让模型动起来(奔跑,攻击,或是跳舞),又或是怎么才能给人物换装,怎么让人物装备 ...

  8. 【Visual C++】游戏开发笔记二十二 游戏基础物理建模 四 粒子系统模拟 一

    分享一下我老师大神的人工智能教程.零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow 本系列文章由zhm ...

  9. 银行使用计算机实现个人存款,江苏计算机二考试基础知识重点题

    1.江苏省计算机二级考试基础知识题(吉根林大学计算机教程高教出版社2016年12月第4次印刷)第1章 绪 论1.1 计算机概述1 . 长期以来,人们都按照计算机主机所使用的元器件为计算机划代,安装了高 ...

最新文章

  1. C代码生成图片:BMP、PNG和JPEG
  2. 授权公钥登录,sudo权限脚本
  3. RocketMQ-初体验RocketMQ(10)-过滤消息_SQL92表达式筛选消息
  4. 乡镇快递站20万入股50%,每天派件600,是否靠谱?
  5. python安装wxpython库_wxPython:python 首选的 GUI 库
  6. MyBatis四大核心概念
  7. ReportLab for PDF
  8. object转class_从零并发框架(三)异步转同步注解+字节码增强代理实现
  9. 权限申请弹框_安卓Q | 位置权限三态化解析,用户要关心,开发者须警惕!
  10. MySql ALTER用法
  11. steamcommunity302怎么用【使用方法】
  12. 区块链专利申请全球过半 厉害了我的国
  13. PAT2021年冬(满分题解)
  14. Motorola ME525 刷机教程
  15. Pdf怎么设置页码,从正文开始
  16. Windows10制作双系统来越狱 ios13.3.1(非常方便,不要U盘)
  17. [图形计算器]Desmos
  18. 瘦臀瘦腿的最快方法是什么?
  19. python 列表 元祖_Python_列表与元祖
  20. 完善自我----女人是需要男人爱护的!

热门文章

  1. [转]兰迪.波许的最后讲座:真正实现你童年的梦想(中英文对照)12
  2. web综合 限时秒杀效果的制作
  3. Hystrix 熔断器 详细介绍
  4. Linux期末考试复习大纲
  5. 手机您的浏览器不允许第三方_手机壁纸:我的世界不允许你的消失,不管结局是否完美...
  6. 光与影的地平线:手机AI摄影全析
  7. Mysql偶尔连接失败的问题
  8. 条码打印出现乱码的解决方案
  9. 5-(4-羟基苯基)-10,15,20-三-(4-溴苯基)卟啉(TPP-Brs)/2-羟甲基-5,10,15,20-四苯基卟啉/2-氯甲基5,10,15,20-四苯基卟啉齐岳供应
  10. Access to XMLHttpRequest at ‘http://localhost:8082/sockjs-node/info?t=1610442684722‘ from origin ‘ht