依赖注入这个模式(模式已经用烂了,这里再烂一次)是用来给应用的各部分解耦的。使应用开发更加可扩展,更容易维护。通过本文你会学到如何使用Dagger2来处理依赖。

简介

如果以对象需要另外的一个对象才能完成一个完整功能的话,那么这里就存在一个依赖。比如,悟空要用金箍棒才能三打白骨精,要筋斗云才能十万八千里。悟空有对金箍棒和筋斗云的依赖。你可以在悟空对象里初始化金箍棒,也可以用一个工厂方法批量生产金箍棒。使用依赖注入可以无需一个专门的类来初始化这些依赖对象。这样就实现了解耦。

本教程会使用***的Dagger2(当前的版本是2.2)。这里是官网。你可以在这里找到***的发布。

准备

Android Studio是必须的。其他:

1. Dagger2 基础

注解讲解:

@Module这个annotation修饰的类专门用来提供依赖

@Provides这个annotation修饰的方法用在Module类里

@Inject用来annotation一个依赖(可以是构造方法、field或者一般的方法)

@Component连接@Module和注入的桥梁

这些名词看起来非常抽象。下面稍微解释一下。依赖反射并没有什么神奇的地方。只不过是我们需要单独写初始化依赖的地方由其他的框架代替了。这个依赖关系也有我们常写的代码转移到了“配置文件”中。

在很久以前,依赖注入的框架就是这样处理依赖注入的:读取配置文件的依赖关系,然后用反射的方法初始化被依赖对象并赋值给调用依赖的对象。比如,我们之前在悟空类中初始化金箍棒:

publicclass Wukong {

private Jingubang jingubang;

publicWukong(){

// 依赖

this.jingubang = Jingubang();

}

}

后来有了使用配置文件的依赖注入(这里都是虚构的文件格式):

在悟空使用金箍棒的时候,依赖注入框架自动初始化好了金箍棒,并赋值给了悟空。

现在使用Dagger2。这里就有不得不说的牛X的地方了。因为是在Android里能用的资源没有后端那么多。尤其反射消耗比较大!所以Dagger为了满足移动开发节约资源的需要,没有使用反射实现依赖注入。而是在编译的时候同时生成依赖注入的相关代码。生成代码的根据就是前文中说明的那些注解(annotation)以及使用这些annotation的类、接口。

总结起来就一句话,Dagger把你需要在悟空类里写的金箍棒类的初始化代码都根据注解替你自动生成了!只不过这种生成的代码比明晃晃的使用new初始化的方法更加复杂一些。

Dagger2 开发步骤

把大象装冰箱一共分几步:

定义依赖和被依赖的对象的类,悟空类和金箍棒类。“悟空类”和“金箍棒类”的构造函数用@Inject注解修饰。

定义一个@Module注解的类,一般叫做XXXModule。里面写的@Provides注解修饰的方法。这些@Provides方法返回“悟空类”和“金箍棒类”对象。比如@Provides Wukong provideWukong(){ return new Wukong(); }

创建一个interface,并用@Component注解修饰。一般叫做XXXComponent。里面写一个注入方法:void inject(Wukong wk);。这里Wukong只是一个例子。任何你准备要注入的类都可以代替上面参数的Wukong类。

在需要注入的地方写@Inject的field。

***,Dagger会根据上面的内容和***的@Component接口生成一个DaggerXXXComponent的类型,使用这个类型来实现注入。上面的1到3步可以理解为依赖的配置。***的XXXComponent代替古老的Reflect方式实现注入。

***步的@Inject修饰的构造函数和`@Module`的`provideXXX`方法二者可以省略一个。

Dagger可以根据其中的任意一种配置创建依赖的对象。都写上等于有了双保险。

上文提到过多次。Dagger 2厉害的地方就在于这个库完全不用反射,而是用在编译期生成代码的方式实现的依赖注入。这个特点导致在Android Studio配置的时候需要做一些额外的工作。

这里假设你已经创建了一个新的Android应用项目。下面打开build.gradle文件,我们一步一步的来完成Dagger2的配置。

3. Android Studio的配置

***步

apply plugin:'kotlin-android'// 非必须

apply plugin: 'kotlin-android-extensions'// 必须!!!

为什么要加一个新的plugin呢?这个是为后面使用的kapt和provided提供支持的。gradle本身不支持这两个操作。

第二步

buildscript {

ext.kotlin_version = '1.0.1-2'

repositories {

mavenCentral()

}

dependencies {

classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version"

}

}

第三步

dependencies {

// ...其他略...

compile 'com.google.dagger:dagger:2.2'

kapt 'com.google.dagger:dagger-compiler:2.2'

provided 'javax.annotation:jsr250-api:1.0'

}

dagger, 我们要用的正主。

dagger-compiler, 用来生成代码。

java.annotation, 提供Dagger意外的注解

***,同步Gradle。

使用Dagger 2

下面就是Dagger一展身手的时候了。

首先,我们已经有悟空和金箍棒了。代码如下:

悟空:

import javax.inject.Inject;

/**

* Created byuncle_charlieon6/4/2016.

*/

publicclass Wukong {

@Inject

JinGuBang jinGuBang;

@Inject

publicWukong() {

}

publicString useJinGuBang() {

returnthis.jinGuBang.use();

}

}

金箍棒:

import javax.inject.Inject;

/**

* Created byuncle_charlieon6/4/2016.

*/

publicclass JinGuBang {

@Inject

publicJinGuBang() {

}

publicString use() {

return"user Jing gu bang";

}

}

悟空对金箍棒有依赖,所以金箍棒属性有@Inject注解修饰。

因为两个类都需要Dagger创建,所以在构造函数上都有@Inject注解。

第二步 创建@Module类

创建@Module注解的类,并在其中添加@Provides注解修饰的方法。这些方法创建被依赖的对象。

import dagger.Module;

import dagger.Provides;

/**

* Created byuncle_charlieon6/4/2016.

*/

@Module

publicclass XiYouModule {

@Provides

//    @Singleton

Wukong provideWukong() {

returnnew Wukong();

}

@Provides

//    @Singleton

JinGuBang provideJinGuBang() {

returnnew JinGuBang();

}

}

@Singleton注解表明,这个被依赖的对象在应用的生命周期里只有一个实例。

这个里的@Provides方法和前一步说到的@Inject注解的构造函数两个可以只写一个。

第三步 @Component接口,连接@Module和@Inject

@Module和@Provides方法提供了被依赖的对象。@Inject在@Component接口出现的地方则是指明了需要注入的地方(一般是一个field)。@Component接口就是用来把他们连接起来的。

import android.app.Activity;

import javax.inject.Singleton;

import dagger.Component;

/**

* Created byuncle_charlieon6/4/2016.

*/

@Component(modules = {XiYouModule.class})

@Singleton

publicinterface XiYouComponent {

void inject(Wukong wk);

void inject(Activity a);

}

其中inject()方法里使用的对象,就是包含@Inject的field的需要注入的对象。

在这个接口中也可以不用inject()方法,而使用provideXXX()方法后面会有更多介绍。

注意:@Component接口一定要在直接中指明@Module类型

第四步 使用@Component接口获取对象

经过前面的步骤,依赖和被依赖对象关系都已经配置好了。下面就来获取被依赖对象来注入依赖对象。

publicclass MainActivity extends AppCompatActivity {

private staticfinal String TAG ="##MainActivity";

@Inject

Wukong wukong;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

TextView welcomeTextView = (TextView) findViewById(R.id.welcome_textview);

// 1

XiYouComponent xiYouComponent = DaggerXiYouComponent

.builder()

// 2

.xiYouModule(new XiYouModule())

.build();

xiYouComponent.inject(this);

// 3

welcomeTextView.setText(wukong.useJinGuBang());

}

}

首先主要到属性@Inject Wukong wukong;已经在MainActivity 声明了。这里表明一个依赖关系:这个activity依赖于悟空,并准备注入悟空对象。

Dagger2会在编译器自动生成依赖注入的代码,所以在添加上面的代码之前需要编译一下。DaggerXiYouComponent就是Dagger根据我们的XiYouModule类生成的代码。

在这一步给DaggerXiYouComponent的builder添加XiYouModule的实例。如果这个Module只需要用到无参构造函数的话可以用一种省略用法:create()方法。可以简写为:

DaggerXiYouComponent

.builder()

// 2

//.xiYouModule(new XiYouModule())

//.build()

.create();

Component接口的对象调用inject(this)方法之后注入即完成。所以可以直接使用@Inject Wukong wukong;属性来调用方法:welcomeTextView.setText(wukong.useJinGuBang());***在activity中显示方法返回的文字。

运行代码,看看结果吧。

结论

以上内容可以概括为:什么被依赖,就把什么放在@Module类里(或者什么被依赖,就给什么添加@Inject的无参构造函数)。什么有依赖(@Inject属性),就把什么放在@Component接口的inject()方法参数里。(或者有什么@Inject属性,就在@Component接口里provide什么对象)。这个概括不一定严密,但是基本用法全部包括了。

依赖注入是很有用的。以上的内容只是Dagger2依赖注入的一部分。各位读者还需要根据官方文档多加练习才能更好的理解依赖注入和Dagger的各种用法。

【编辑推荐】

【责任编辑:枯木 TEL:(010)68476606】

点赞 0

android dagger2 讲解,用Dagger2在Android中实现依赖注入相关推荐

  1. android dagger2 讲解,告别Dagger2模板代码:DaggerAndroid原理解析

    本系列所有文章: 概述 距离我的上一篇文章发布以来,有幸收获了一些朋友的认可,我很开心. 在上一篇文章中,我简单叙述了Dagger2这个库目前在Android开发中的一些短板,为什么我们学习Dagge ...

  2. dagger2 注入_如何使用Dagger 2在您的应用程序中实现依赖注入

    dagger2 注入 Kriptofolio应用程序系列-第4部分 (Kriptofolio app series - Part 4) Dependency injection will signif ...

  3. ASP.NET Core中的依赖注入(4): 构造函数的选择与服务生命周期管理

    ServiceProvider最终提供的服务实例都是根据对应的ServiceDescriptor创建的,对于一个具体的ServiceDescriptor对象来说,如果它的ImplementationI ...

  4. .NET CORE——Console中使用依赖注入

    我们都知道,在 ASP.NET CORE 中通过依赖注入的方式来使用服务十分的简单,而在 Console 中,其实也只是稍微绕了个小弯子而已.不管是内置 DI 组件或者第三方的 DI 组件(如Auto ...

  5. 转: 理解AngularJS中的依赖注入

    理解AngularJS中的依赖注入 AngularJS中的依赖注入非常的有用,它同时也是我们能够轻松对组件进行测试的关键所在.在本文中我们将会解释AngularJS依赖注入系统是如何运行的. Prov ...

  6. JavaEE开发之Spring中的依赖注入与AOP编程

    上篇博客我们系统的聊了<JavaEE开发之基于Eclipse的环境搭建以及Maven Web App的创建>,并在之前的博客中我们聊了依赖注入的相关东西,并且使用Objective-C的R ...

  7. 理解AngularJS中的依赖注入

    作者 CraftsCoder 冷月无声 - 博客频道 - CSDN.NET http://blog.csdn.net/jaytalent/article/details/50986402 本文结合一些 ...

  8. spring中的依赖注入——构造函数注入、set方法注入( 更常用的方式)、复杂类型的注入/集合类型的注入

    spring中的依赖注入 依赖注入: Dependency Injection IOC的作用:降低程序间的耦合(依赖关系) 依赖关系的管理:以后都交给spring来维护.在当前类需要用到其他类的对象, ...

  9. Angular 中的依赖注入link

    Angular 中的依赖注入link 依赖注入(DI)是一种重要的应用设计模式. Angular 有自己的 DI 框架,在设计应用时常会用到它,以提升它们的开发效率和模块化程度. 依赖,是当类需要执行 ...

  10. ASP.NET CORE MVC 2.0 如何在Filter中使用依赖注入来读取AppSettings

    问: ASP.NET CORE MVC 如何在Filter中使用依赖注入来读取AppSettings 答: Dependency injection is possible in filters as ...

最新文章

  1. SAP PI - 同步 vs. 异步
  2. Delphi的对象注销方法Destroy和free的区别
  3. 【转】最佳 WordPress 缓存插件:WP Super Cache
  4. 单调有界数列一定有极限
  5. 博弈论(Game Theory) - 04 - 纳什均衡
  6. 手写数字识别项目代码——卷积神经网络LeNet-5模型
  7. Android 自动化测试框架简介
  8. 方法调用_thinkphp跨模块调用方法
  9. CentOS服务器下nginx防盗链介绍与配置
  10. CSDN博客代码高亮显示
  11. DB2入门(5)——DB2配置文件
  12. xp升级到win7傻瓜教程_重装系统软件哪些比较好_windows7教程
  13. SPSS纵向数据格式转换为横向数据格式时变量不是自己想要
  14. 360极速浏览器极速模式通过hosts文件切换兼容模式bat脚本
  15. KepOPC全新DA2UA中间件实现OPCDA与UA的转换及互操作
  16. MBA-day13 逻辑学 模态推理(可能与必然的推理)
  17. 黑马就业班(01.JavaSE Java语言基础-11.Java基础加强)——基础加强:Junit单元测试、反射、注解
  18. 选购kvm需要注意的重要事项
  19. PyCharm配置解释器
  20. matlab与python语法区别(持续更新)

热门文章

  1. 微信小程序UI框架记录
  2. Tk-Mybatis(通用mybatis)简单使用
  3. 用旧电脑安装黑群晖系统
  4. 游戏BOSS关卡的设计
  5. 图像边缘检测的新方向——量子算法
  6. 说说百度iOS人脸识别的痛
  7. scada系统集成_MES与EPR进行系统集成的实际案例-系统接口、交互数据分析
  8. Vue-pdf预览pdf文档
  9. java实现pdf预览和下载
  10. 一个不错的Redis实战学习视频教程