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
Android 进阶Dagger2 系列(入门案例一)

文章图片
 
- Container 拥有者,容器等意思,其中 Activity 就是 Dagger2 中的 Container. 
- Component Acitvity 和 依赖对象之间的一个桥梁。 
- Module 就是负责提供对象的。
用到的注解如下:
@Inject: 
通常在需要依赖的地方使用这个注解。换句话说,你用它告诉 Dagger 这个类或者字段需要依赖注入。这样,Dagger 就会构造一个这个类的实例并满足他们的依赖。
@Module: 
Modules 类里面的方法专门提供依赖,所以我们定义一个类,用 @Module 注解,这样 Dagger 在构造类的实例 
时候,就知道从哪里去找到需要的 依赖。modules 的一个重要特征是它们设计为分区并组合在一起(比如说, 
我们的 app 中可以有多个组成在一起 的modules)
@Provide: 
在 modules 中,我们定义的方法是用这个注解,以此来告诉 Dagger 我们想要构造对象并提供这些依赖。
【Android 进阶Dagger2 系列(入门案例一)】@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























    推荐阅读