首页 > 代码库 > 【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 系列:入门案例一