首页 > 代码库 > 【Android 进阶】Dagger2 系列:入门案例一
【Android 进阶】Dagger2 系列:入门案例一
介绍
A fast dependency injector for Android and Java.
一个在 Android 和 Java 平台上使用的快速的依赖注入框架。
类似 java 开发中的 spring 框架,但使用难度比 spring 大一点点。
依赖注入框架主要用于模块间解耦,提高代码的健壮性和可维护性。
几个必须知道的概念:
什么是依赖:
如果在 Class A 中,有 Class B 的实例,则称 Class A 对 Class B 有一个依赖。
什么是依赖注入:
依赖注入就是非自己主动初始化依赖,而通过外部来传入依赖的方式,简单来说就是不使用 new 来创建依赖对象。
三大元素:
必不可少的元素有三种,Module,Component,Container
- Container 拥有者,容器等意思,其中 Activity 就是 Dagger2 中的 Container.
- Component Acitvity 和 依赖对象之间的一个桥梁。
- Module 就是负责提供对象的。
用到的注解如下:
@Inject:
通常在需要依赖的地方使用这个注解。换句话说,你用它告诉 Dagger 这个类或者字段需要依赖注入。这样,Dagger 就会构造一个这个类的实例并满足他们的依赖。@Module:
Modules 类里面的方法专门提供依赖,所以我们定义一个类,用 @Module 注解,这样 Dagger 在构造类的实例
时候,就知道从哪里去找到需要的 依赖。modules 的一个重要特征是它们设计为分区并组合在一起(比如说,
我们的 app 中可以有多个组成在一起 的modules)@Provide:
在 modules 中,我们定义的方法是用这个注解,以此来告诉 Dagger 我们想要构造对象并提供这些依赖。@Component:
Components 从根本上来说就是一个注入器,也可以说是 @Inject 和 @Module 的桥梁,它的主要作用就是连接这两个部分。 Components 可以提供所有定义了的类型的实例,比如:我们必须用 @Component 注解一个接口然后列出所有的
官方 Github 地址以及 API 说明文档::
google/dagger
说明文档
使用准备:
project 的 build.gradle 添加
dependencies {
... // 其他 classpath
classpath ‘com.neenbedankt.gradle.plugins:android-apt:1.8‘ //添加 apt 命令
}
module 的 build.gradle 添加
// 添加其他插件
apply plugin: ‘com.neenbedankt.android-apt‘//添加 apt 命令
dependencies {
apt ‘com.google.dagger:dagger-compiler:2.0.2‘ //指定注解处理器
compile ‘com.google.dagger:dagger:2.0.2‘ //dagger 公用 api
provided ‘org.glassfish:javax.annotation:10.0-b28‘ //添加 android 缺失的部分 javax 注解
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
直接从代码出发吧
代码完整,可以直接粘贴到自己 AS 验证。
看一个简单的例子:
代码如下:
MainActivity.java
/**
* Created by Veyron on 2017/5/9.
* Function:直接依赖注入 ApiService 对象
*/
public class MainActivity extends AppCompatActivity {
@Inject
ApiService mApiService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//rebuild一下,自动生成 DaggerUserComponet 类
DaggerUserComponet.create().inject(this);
mApiService.register();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
ApiService.java
/**
* Created by Veyron on 2017/5/9.
* Function:
*/
public class ApiService {
public void register(){
Log.e("ApiService","register");
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
UserModule.java
/**
* Created by Veyron on 2017/5/9.
* Function:提供实例的 Module
*/
@Module
public class UserModule {
@Provides
public ApiService provideApiService(){
Log.e("UserModule","provideUserManger");
return new ApiService();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
UserComponet
/**
* Created by Veyron on 2017/5/9.
* Function:Activity 和 Module 之间的桥梁
* @Component(modules = {UserModule.class}) 表示和 Module 对接
*
* void inject(MainActivity activity);表示在 MainActivity 中注入
*/
@Component(modules = {UserModule.class})
public interface UserComponet {
void inject(MainActivity activity);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
输出:
E/UserModule: provideApiService
E/ApiService: register
- 1
- 2
- 1
- 2
更复杂一点的例子:
MainActivity.java
/**
* Created by Veyron on 2017/5/9.
* Function:直接依赖注入 UserManger 对象
*/
public class MainActivity extends AppCompatActivity {
/* @Inject
ApiService mApiService;*/
@Inject
UserManger mUserManger;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DaggerUserComponet.builder()
.userModule(new UserModule()).build().inject(this);
//DaggerUserComponet.create().inject(this); 等价上面
mUserManger.register();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
ApiService.java
/**
* Created by Veyron on 2017/5/9.
* Function:直接依赖注入 UserManger 对象
*/
public class ApiService {
//当module里面没有提供本类的对象,默认调用下面这个 @Inject 注释的构造函数(只能声明一个)
@Inject
public ApiService(){
Log.e("ApiService","ApiService的构造函数");
}
/* @Inject
public ApiService(String url){
Log.e("ApiService","url---");
}*/
public void register(){
Log.e("ApiService","register");
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
UserModule.java
/**
* Created by Veyron on 2017/5/9.
* Function:
*/
@Module
public class UserModule {
@Provides
public ApiService provideApiService(){
Log.e("UserModule","provideApiService-");
return new ApiService();
}
@Provides
public String url(){
return "url";
}
// 将会调用这个 public ApiService(String url) 方法
//单独调用本方法的话,apiService 的对象是上面提供的,另一种使用 apiservice 的构造方法
@Provides
public UserManger provideUserManger(ApiService apiService){
Log.e("UserModule","provideUserManger");
return new UserManger(apiService);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
UserComponet.java
/**
* Created by Veyron on 2017/5/9.
* Function:Activity 和 Module 之间的桥梁
* @Component(modules = {UserModule.class}) 表示和 Module 对接
*
* void inject(MainActivity activity);表示在 MainActivity 中注入
*/
@Component(modules = {UserModule.class})
public interface UserComponet {
void inject(MainActivity activity);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
输出如下:
E/UserModule: provideApiService
E/ApiService: ApiService 的构造函数
E/UserModule: provideUserManger
E/UserManger: register
E/ApiService: register
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
更复杂点
第二个例子其中,将 UserModule.java,UserModule.java 改动如下:
UserModule.java
/**
* Created by Veyron on 2017/5/9.
* Function:
*/
@Module
public class UserModule {
/*@Provides
public ApiService provideApiService(){
Log.e("UserModule","provideApiService");
return new ApiService();
}*/
@Provides
public String url(){
return "传给 ApiService 构造函数的参数";
}
// 将会调用这个 public ApiService(String url) 方法
//单独调用本方法的话,apiService 的对象是上面提供的,另一种使用 apiservice 的构造方法
@Provides
public UserManger provideUserManger(ApiService apiService){
Log.e("UserModule","provideUserManger");
return new UserManger(apiService);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
ApiService.java
/**
* Created by Veyron on 2017/5/9.
* Function:@Inject 声明的构造函数只能有一个
*/
public class ApiService {
//当module里面没有提供本类的对象,默认调用下面这个 @Inject 注释的构造函数(只能声明一个)
/*@Inject
public ApiService(){
Log.e("ApiService","ApiService的构造函数");
}*/
@Inject
public ApiService(String url){
Log.e("ApiService","url="+url);
}
public void register(){
Log.e("ApiService","register");
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
输出是:
E/ApiService: url=传给ApiService构造函数的参数
E/UserModule: provideUserManger
E/UserManger: register
E/ApiService: register
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
看了输出,再参考下代码,其实就知道是怎么回事了。
可以得到一点结论就是:在 UserModule 中需要 ApiService 对象,但是 UserModule 中并没提供,那么就去查看 ApiService 中有没有 @Inject 声明的构造函数,如果有且是无参构造函数,那么 UserModule 中就相当拿到了 ApiService 对象。如果是有参的构造函数,则 UserModule 中必须有提供该参数的实例,如本例子中的 public String url() 函数,返回的 String 就是给构造函数当参数的,那么 UserModule 中就等于有了 ApiService 对象。
声明
建议把上面的例子都运行一遍,就会有体会 Dagger2 的使用是怎样的。
篇幅有限,Dagger2 使用方式也有很多, 下一篇接着介绍 其他例子。
http://blog.renren.com/blog/937184755/994083793
http://blog.renren.com/blog/937184755/994083886
http://blog.renren.com/blog/937184755/994084167
http://gamebbs.51.com/thread-324928-1-1.html
http://blog.163.com/m13094739605_1/blog/static/27240604620174100133493/
http://blog.163.com/m13094739605_1/blog/static/2724060462017410028912/
http://blog.163.com/m13094739605_1/blog/static/27240604620174100237428/
http://blog.163.com/m13094739605_1/blog/static/27240604620174100315903/
http://www.230la.com/com/wz801234567/news/itemid-3253535.html
【Android 进阶】Dagger2 系列:入门案例一