前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Dagger2 使用总结(一)

Dagger2 使用总结(一)

作者头像
Seven Du
发布2020-12-21 16:03:32
9950
发布2020-12-21 16:03:32
举报

Dagger2 使用总结(一)

重阳节,又称重九节、晒秋节、“踏秋”,中国传统节日。庆祝重阳节一般会包括出游赏秋、登高远眺、观赏菊花、遍插茱萸、吃重阳糕、饮菊花酒等活动。

Dagger2是一套依赖注入框架,在编译期间自动生成代码,创建依赖的对象。项目中使用Dagger2可以降低代码的耦合度。 使用Dagger2库,重点是了解其中的各种注解并熟练使用,下面看一下具体用例。

注:为了能够更直观地了解Dagger2的使用,本文用例会尽量简化不相关的业务逻辑

环境配置

配置下build.gradle即可

@Inject和@Component注解

使用@Inject和@Component注解是Dagger2最基本的使用方式,来看一个简单的Demo,向 MainActivity 里注入 Apple:

编写 Apple类代码

编写 MainActivity 类代码

编译项目

这时候编译项目会在build目录下生成以下文件:

Apple_Factory.java DaggerMainActivity_MainActivityComponent.javaMainActivity_MembersInjector.java

这些文件是Dagger2框架帮我们自动生成的,用于帮我们注入依赖。

在 MainActivity 注入依赖

使用依赖注入

如果不使用依赖注入,那写法将会是下面这样:

这样看起来比不使用Dagger2注入对象要简单很多,但是如果对象引用的地方很多,构造复杂,那么一旦改变构造,工作量会很大,这也是Dagge2最重要的优势——解耦。

小结

以上是Dagger2最简单的使用方法,注入依赖后,会用在Apple类中标注@Inject注解的构造器自动创建apple对象。而@Component标注的接口用于连接目标类和注入类的工厂Apple_Factory。

方法注入

如果注入的对象需要设置为private,那我们可以使用方法注入,示例:

private Apple apple;@Injectpublic void setApple(Apple apple) { this.apple = apple; }

上述代码作用等同于:

@Injectpublic Apple apple;

拓展

如果现在需要修改Apple类的构造器,需要加一个Color参数,如下:

这时候构造器中的color也需要注入依赖,创建一个简单的Color类并在构造器上标注注解@Inject即可

这样在构建apple对象时会寻找标注了@Inject注解的Color的构造器新建color对象用于apple对象的构造。除了@Inject和@Component之外,Dagger2中还有其他注解,下文会说明。

@Modele和@Provides注解

@Inject注解存在局限性,以下两种情况时不能使用:

· 注入的对象来自第三方库

· 注入的对象声明为抽象类或接口(依赖倒置原则)

比如上述的例子修改下,添加一个抽象类Fruit:

修改后Apple类继承Fruit:

这时候,如果只按照下面的形式声明,是无法注入apple对象的,运行会报错

@Inject

public Fruit apple;

这时候就需要用到@Modele和@Provides注解,完整示例如下:

创建Fruit类和Apple类

Fruit抽象类:

Apple类:

创建Module类

在MainActivity中注入对象

小结

使用@Inject和@Component注解注入对象时, 我们需要在声明的注入类的构造器上加上@Inject注解来使对象被创建。

如果遇到注入类构造器不方便编辑时(比如来自三方库,抽象类,接口), 则可以使用@Module和@Provides注解,将对像获得由构造器获得转变为由方法返回,使对象的创建形式更加可控。

再形象看一下两者的区别(不想看可以跳过):

仅使用@Inject和@Component注入对象build目录下生成的文件如下 Apple_Factory.java DaggerMainActivity_MainActivityComponent.javaMainActivity_MembersInjector.java

使用@Module和@Provides注入对象build目录下生成的文件如下 FruitModule_ProvideAppleFactory DaggerMainActivity_MainActivityComponent.javaMainActivity_MembersInjector.java

区别在于前者是Apple_Factory.java而后者是FruitModule_ProvideAppleFactory, 这两个类都是用于提供对象的, 而DaggerMainActivity_MainActivityComponent.java类实现了MainActivityComponent接口, 用于将目标类和提供对象的类连接起来。

所以两者的区别仅在于提供对象的方式不同,再具体可以看这两个差异类的实现。

拓展

Component接口可以指定多个Module类,便于将它们一起注入,比如在这个例子中,可以按下述方式编写:

这样我们便可以注入OtherModule中可以获得的对象。

@Named注解

上述的@Module和@Provides注解仅能返回一个继承了Fruit的对象, 如果再加入一个Banana类,继承Fruit并在MainActivity中注入, 这时候就需要使用@Named注解。基于上述代码,示例如下:

新建Banana类

修改FruitModule类

修改MainActivity类

小结

@Named注解使用比较简单,只要将Module类中的标注和目标类中声明注入类的标注一一对应即可。

@Qualifier注解

@Qualifier注解的作用和@Named相同,只是实现有所区别,直接看示例:

修改FruitModule类

修改MainActivity类

小结

@Qualifier和@Named注解作用是一样的, 区别是@Named使用字符串来区分不同的返回对象,

而@Qualifier用自定义的接口来区分,这样可以提高代码的可读性,且不容易出错。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-10-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 FreeSWITCH中文社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档