Android项目使用Dagger2进行依赖注入
原文链接:http://code.tutsplus.com/tutorials/dependency-injection-with-dagger-2-on-android–cms-23345
依赖注入是一种软件设计模式,致力于应用松耦合,可扩展性和可维护性。
本教程中,将学到怎样使用Dagger2进行依赖注入。
介绍
当一个对象须要或依靠其它对象处理工作时,这就是一个依赖关系。依赖关系能够通过让依赖对象创建被依赖者或者使用工厂方法创建一个被依赖者来解决。在依赖注入的情况下,然而。向类提供的依赖须要避免类来创建它们。
这样你创建的软件就是松耦合和高可维护的。
本教程使用Dagger的最新版。Dagger 2。在写作期间。Dagger 2还未正式公布,处于pre-alpha阶段。然而。它是可用和稳定的。你能够訪问Dagger on GitHub得到项目的新闻和正式版的公布日期。
前置条件
你须要在开发机上安装最新版的Android Studio。能够从Android开发人员站点下载。
Dagger 2 API
Dagger 2提供了一些特殊的注解:
@Module
用于类。该类的方法提供依赖。@Provides
用于@Module
注解的类中的方法@inject
请求依赖(用在构造函数,域或方法)@Component
是模块和注入之间的接口
这些就是即将使用Dagger 2进行依赖注入所须要了解的重要注解。我将在一个简单Android应用中向你展示怎样使用它们。
Dagger 2工作流程
为了正确使用Dagger 2,你须要遵守下面步骤:
- 识别依赖对象和它的依赖。
- 创建带
@Module
注解的类。对每一个返回依赖的方法使用@Provides
注解。 - 在依赖对象上使用
@Inject
注解来请求依赖。 - 使用
@Componet
注解创建一个接口并添加第二步中创建的带@Module
注解的类。 - 创建一个
@Component
接口的对象来实例化自带依赖的依赖对象。
依赖分析从执行时转换到编译时。
这意味着在开发阶段就能够知道可能的问题。而不像其它的库。比如Guice。在開始使用Dagger 2库之前。你须要安装Android Stuido来訪问生成的类。
Android Studio环境建立
Step 1
使用Android Studio创建一个新的应用并命名。我的project命名为TutsplusDagger。
Step 2
设置项目的最小SDK版本号为API 10来适配很多其它机型。
Step 3
创建的activity选择空布局。对于本教程。不须要特殊布局。
Step 4
命名activity为Main
Activity并点击Finishbutton。
project创建后,你须要对gradle文件进行一些改动。让我们在下一步中做这些改动。
配置Gradle设置。
Step 1
我们须要改动project的build.gradle文件例如以下:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.0.0'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'
}
}
allprojects {
repositories {
mavenCentral()
maven{
url 'https://oss.sonatype.org/content/repositories/snapshots/'
}
}
}
让我们看一下做了哪些改动:
- dependencies:这部分。我添加了一个插件,该插件将用于訪问Dagger生成的文件。假设不加入,訪问这些新类时将看到错误。
- allprojects:这个改动是由于我们使用的库当前处于pre-alpha阶段,而且这是使用Maven来訪问该库的唯一可用地址。也能够从Sonatype下载Dagger和Dagger编译器库。但本教程是基于Maven仓库创建的。
####Step 2
打开projectapp目录中的build.gradle文件,改动例如以下:
apply plugin: 'com.android.application'
apply plugin: 'com.neenbedankt.android-apt'
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
applicationId "com.androidheroes.tutsplusdagger"
minSdkVersion 10
targetSdkVersion 21
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:21.0.3'
compile 'com.google.dagger:dagger:2.0-SNAPSHOT'
apt 'com.google.dagger:dagger-compiler:2.0-SNAPSHOT'
provided 'org.glassfish:javax.annotation:10.0-b28'
}
在文件开头,我应用了新的插件。
务必将新插件(com.neenbedankt.android-apt)放到Android插件之后。假设不这样做,在同步project的gradle文件时将显示错误。
在dependencies中加入了例如以下依赖:
- dagger库
- dagger-compiler用于代码生成
- javax.annotation用于Dagger之外需求的额外注解
在更新Dagger的配置后,你须要点击上面的button来同步project的gradle文件。
到这里,你的应用已经有了一个能够准备使用的空项目。
假设有错误,请确保你正确的遵守以上步骤。如今我们来实现我们的栗子项目。
实现Dagger 2
Step 1:识别依赖对象
对于本教程。我打算实现两个类。
Vehicle
和Motor
。Motor
是独立类,Vehicle
是依赖类。我打算開始在包名为model
中创建这个模型。Motor
类结构例如以下:
package com.androidheroes.tutsplusdagger.model;
/**
* Created by kerry on 14/02/15.
*/
public class Motor {
private int rpm;
public Motor(){
this.rpm = 0;
}
public int getRpm(){
return rpm;
}
public void accelerate(int value){
rpm = rpm + value;
}
public void brake(){
rpm = 0;
}
}
该类仅仅有一个名为rmp
的属性。我准备通过accelerate
和brake
方法来改动它。而且使用getRpm
方法来訪问当前值。
Vehicle
类结构例如以下:
package com.androidheroes.tutsplusdagger.model;
/**
* Created by kerry on 14/02/15.
*/
public class Vehicle {
private Motor motor;
public Vehicle(Motor motor){
this.motor = motor;
}
public void increaseSpeed(int value){
motor.accelerate(value);
}
public void stop(){
motor.brake();
}
public int getSpeed(){
return motor.getRpm();
}
}
在类中。你看到我没有创建Motor
类的新对象。即使使用了它的方法。
在真实世界的应用中,这个类应当有很多其它的方法和属性。但如今尽量保持简单。
####Step 2:创建@Module
类
如今要创建带@Module
注解的类。
该类将提供自带依赖的对象。由于这点,须要创建新的包名(仅仅是为了保持顺序)。命名为module
并在当中添加新类,代码例如以下:
package com.androidheroes.tutsplusdagger.module;
import com.androidheroes.tutsplusdagger.model.Motor;
import com.androidheroes.tutsplusdagger.model.Vehicle;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
/**
* Created by kerry on 14/02/15.
*/
@Module
public class VehicleModule {
@Provides @Singleton
Motor provideMotor(){
return new Motor();
}
@Provides @Singleton
Vehicle provideVehicle(){
return new Vehicle(new Motor());
}
}
在Step 1中我指出。Vehicle
须要Motor
来正常工作。这就是为什么你须要创建两个提供者,一个给Motor
(独立模型)。还有一个给Vehicle
(指明它的依赖)。
别忘了每一个提供者(或方法)必须加入@Provides
注解而且类必须有@Module
注解。
@Singleton
注解指明对象仅仅能有一个实例。
####Step 3: 依赖对象中请求依赖
如今不同的模型都有了提供者,你须要请求它们。就像Vehicle
须要Motor
那样,你须要在Vehicle
的构造函数前添加@Inject
注解。代码例如以下:
@Inject
public Vehicle(Motor motor){
this.motor = motor;
}
你能够使用@Inject
注解在构造函数,域,方法中来请求依赖。这个样例里,我在构造函数中使用注入。
####Step 4:使用@Inject
链接@Module
使用带@Component
注解的接口连接依赖的提供者,@Module
。和请求他们的类。这些类标记了@Inject
package com.androidheroes.tutsplusdagger.component;
import com.androidheroes.tutsplusdagger.model.Vehicle;
import com.androidheroes.tutsplusdagger.module.VehicleModule;
import javax.inject.Singleton;
import dagger.Component;
/**
* Created by kerry on 14/02/15.
*/
@Singleton
@Component(modules = {VehicleModule.class})
public interface VehicleComponent {
Vehicle provideVehicle();
}
@Component
注解中,你须要指明打算使用哪个类 —— 本例是VehicleModule
,前面已经创建了。假设你打算使用很多其它的模块。仅仅须要使用逗号作为分隔符来添加它们。
接口中。给每一个须要的对象添加方法,它们会自己主动加入依赖。本例中,由于仅仅须要一个Vehicle
对象,所以仅仅有一个方法。
####Step 5: 使用@Component
接口获取对象
如今万事俱备了。你须要拥有一个接口的实例并调用它的方法来获取须要的对象。我将在MainActivity
中的OnCreate
方法中实现,代码例如以下:
package com.androidheroes.tutsplusdagger;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.widget.Toast;
import com.androidheroes.tutsplusdagger.component.Dagger_VehicleComponent;
import com.androidheroes.tutsplusdagger.component.VehicleComponent;
import com.androidheroes.tutsplusdagger.model.Vehicle;
import com.androidheroes.tutsplusdagger.module.VehicleModule;
public class MainActivity extends ActionBarActivity {
Vehicle vehicle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
VehicleComponent component = Dagger_VehicleComponent.builder().vehicleModule(new VehicleModule()).build();
vehicle = component.provideVehicle();
Toast.makeText(this, String.valueOf(vehicle.getSpeed()), Toast.LENGTH_SHORT).show();
}
当你打算创建一个带@Component
注解的接口对象时,你须要使用Dagger_<NameOfTheComponentInterface>
前缀来实现,本例是Dagger_VehicleComponent
,然后使用builder
方法来调用各个模块。
秘诀就在代码的第23行。你仅仅要求Vehicle
类的一个对象。Dagger2库会负责准备该对象的全部依赖。
相同,你看不到其它不论什么对象的新实例——Dagger2库帮你处理了全部。
如今能够在设备或者模拟器上执行应用。假设依照教程一步一步实现。你将看到一个显示rpm
变量初始值的Toast
消息。
在相关的project里。你能看到一个对MainActivity
类定制的用户接口。该接口中。通过点击屏幕上的button,你能够改动rpm
变量的值。
结论
依赖注入是一个模式,在你的应用中迟早会用到该模式。使用Dagger 2。你拥有了实现依赖注入的利器。我希望该教程对你实用,假设你喜欢它请分享它。
Android项目使用Dagger2进行依赖注入的更多相关文章
- Android 使用dagger2进行依赖注入(基础篇)
0. 前言 Dagger2是首个使用生成代码实现完整依赖注入的框架,极大减少了使用者的编码负担,本文主要介绍如何使用dagger2进行依赖注入.如果你不还不了解依赖注入,请看这一篇. 1. 简单的依赖 ...
- [Android]使用Dagger 2进行依赖注入 - Producers(翻译)
以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/6234811.html 使用Dagger 2进行依赖注入 - P ...
- Android开源项目发现--- 工具类依赖注入DI篇(持续更新)
通过依赖注入减少View.服务.资源简化初始化,事件绑定等重复繁琐工作 1. AndroidAnnotations(Code Diet) android快速开发框架 项目地址:https://gith ...
- [Android]使用Dagger 2依赖注入 - 自定义Scope(翻译)
以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5095426.html 使用Dagger 2依赖注入 - 自定义 ...
- [Android]使用Dagger 2依赖注入 - DI介绍(翻译)
以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5092083.html 使用Dagger 2依赖注入 - DI介 ...
- [Android]使用Dagger 2依赖注入 - API(翻译)
以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5092525.html 使用Dagger 2依赖注入 - API ...
- [Android]使用Dagger 2依赖注入 - 图表创建的性能(翻译)
以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5098943.html 使用Dagger 2依赖注入 - 图表创 ...
- 基于ABP模块组件与依赖注入组件的项目插件开发
注意,阅读本文,需要先阅读以下两篇文章,并且对依赖注入有一定的基础. 模块系统:http://www.cnblogs.com/mienreal/p/4537522.html 依赖注入:http://w ...
- 轻松学,浅析依赖倒置(DIP)、控制反转(IOC)和依赖注入(DI) 依赖注入和控制反转的理解,写的太好了。
轻松学,浅析依赖倒置(DIP).控制反转(IOC)和依赖注入(DI) 2017年07月13日 22:04:39 frank909 阅读数:14269更多 所属专栏: Java 反射基础知识与实战 ...
随机推荐
- XAMPP 下apache部署网站,多个虚拟机(空间)配置
1.首先修改C盘WINDOWS/system32/drivers/etc目录下的 hosts 文件,用记事本打开,加入: 127.0.0.1 www.a.com 127.0.0.1 www.b.com ...
- CSS box-flex属性,然后弹性盒子模型简介(转)
一.淡淡的开头语 昨天趁着不想工作的时间间隙闲逛24ways,在My CSS Wish List一文中,见到了个新鲜的CSS属性,就是题目中的box-flex,以前没有见过,顿生疑惑,不知是骡子还是马 ...
- Asp.Net MVC part1
路由简介在Global中注册了路由数据包括:默认Controller,默认Action,请求地址匹配路由规则 约定大于配置为了尽量少的配置,于是将常用的配置作为默认约定,如果不同则进行少量配置主要从存 ...
- iOS开发——Autolayout下动态调整单元格高度
情景描述: 有时候我们希望更新某一个单元格的数据,通常的做法是使用reloadData方法更新整个单元格.但是对一些情况是不适用的或者说实现起来比较麻烦.比如说这种简单的"点开"一 ...
- BlockTransferService 实现
spark的block管理是通过BlockTransferService定义的方法从远端获取block.将block存储到远程节点.shuffleclient生成过程就会引入blockTransfer ...
- 【java】在分页查询结果中对最后的结果集List进行操作add()或remove()操作,报错:java.lang.UnsupportedOperationException
场景: 在分页查询结果中对最后的结果集List进行操作add()或remove()操作,报错:java.lang.UnsupportedOperationException 错误: java.lang ...
- Ubuntu -- 安装和部署php5.6 nginx php5.6-fpm
1.首先输入用户名和密码进行登录 2.升级更新软件包 sudo apt-get update sudo apt-get upgrade 判断都填y 3.安装nginx sudo apt-get i ...
- win8.1无法安装安装.net framework 3.5 解决办法【转】
安装流程1.以系统管理员开启命令提示符(命令提示字符)2挂载windows8.1异3,在命令提示符下输入Dism /online /enablefeature/featurename:NetFx3 / ...
- webstorm9 License Key
用户名 oschina 注册码 ===== LICENSE BEGIN ===== 7362-D18089T 00000xmyY1VfVxjkElWULKcA5XHbfN 5qjOh3fgGZvNXH ...
- ylbtech-LanguageSamples-COMInteropPart1(COM 互操作 - 第一部分)
ylbtech-Microsoft-CSharpSamples:ylbtech-LanguageSamples-COMInteropPart1(COM 互操作 - 第一部分) 1.A,示例(Sampl ...