Android dagger2

什么是dagger2

Dagger2是Dagger的升级版,是一个依赖注入框架,现在由Google接手维护。 恩,这里有个关键字依赖注入,因此我们得先知道什么是依赖注入,才能更好的理解Dagger2。

依赖注入是面向对象编程的一种设计模式,其目的是为了降低程序耦合,这个耦合就是类之间的依赖引起的。

什么是依赖注入?当 A 类中包含一个属性 B 类,就可以说 A 对 B 产生了 依赖。当实例化一个对象的时候,不再需要 new 出一个实例,而是由框架自动的帮你生成一个实例,这就是 注入

简单的说,就是程序运行之前需要某些基础数据,这些基础数据就叫做依赖的数据。

依赖注入有以下几种方式:

  • 通过接口注入
    interface ClassBInterface {
    void setB(ClassB b);
    }

        public class ClassA implements ClassBInterface {
            ClassB classB;
    
            @override
            void setB(ClassB b) {
                classB = b;
            }
        }
    
  • 通过set方法注入
    public class ClassA {
    ClassB classB;

            public void setClassB(ClassB b) {
                classB = b;
            }
        }
    
  • 通过构造方法注入
    public class ClassA {
    ClassB classB;

            public void ClassA(ClassB b) {
                classB = b;
            }
    
  • 通过Java注解
    public class ClassA {
    //此时并不会完成注入,还需要依赖注入框架的支持,如RoboGuice,Dagger2
    @inject ClassB classB;

            ...
            public ClassA() {}
    

在Dagger2中用的就是最后一种注入方式,通过注解的方式,将依赖注入到宿主类中。

在 Android Studio 中配置 Dagger2

Dagger2 是一个通用的 java 库,并不只适用于 Android,这里仅以 Studio 下的 Android 开发示例。
在项目的根 build.gradle 里添加:

    buildscript {
        ...
        dependencies {
            ... 
            //编译时处理注解的插件,生成代码就靠它
            classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
        }
    }

在module的build.gradle添加:

    apply plugin: 'com.neenbedankt.android-apt'

        android{
            ...
        }

    dependencies {
        provided 'org.glassfish:javax.annotation:10.0-b28'
        compile 'com.google.dagger:dagger:2.5'
        compile 'com.google.dagger:dagger-compiler:2.5'
    }

贴上整个gradle:

    apply plugin: 'com.android.application'
    //dagger add
    apply plugin: 'com.neenbedankt.android-apt'

    android {
        compileSdkVersion 24
        buildToolsVersion "24.0.1"
        defaultConfig {
            applicationId "com.example.ibesteeth.gjj_dagger_demo"
            minSdkVersion 17
            targetSdkVersion 24
            versionCode 1
            versionName "1.0"
            testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        }
        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:24.2.0'
        compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha1'
        testCompile 'junit:junit:4.12'

        //dagger2
        compile 'com.google.dagger:dagger:2.4'
        apt 'com.google.dagger:dagger-compiler:2.4'
        //java注解
        compile 'org.glassfish:javax.annotation:10.0-b28'

        //Square
        compile 'com.jakewharton:butterknife:6.1.0'
        compile 'com.squareup.retrofit:retrofit:1.9.0'
        compile 'com.squareup.okhttp:okhttp:2.3.0'
    }

Dagger2 中的注解

@Module

注解一个类,这个类用来提供依赖,或者通俗的说,完成各种对象的实例化 的一个集合。类里面可以包含很多@Provides
注解的方法,每个方法对应一种对象的创建。

@Provides

注解 Module 类里面的方法,Dagger 会在需要创建实例的时候找到这个方法并调用,完成对象的实例化。

这样说可能还是太抽象,看一个实例:

    //apiservice的工厂类
    @Module
    public class ApiServiceModule {

        @Provides
        int getId(){
            return 0;
        }

        @Provides
        String getName(){
            return "testName";
        }

        @Provides
        @Singleton
        ApiService provideApiServiceNull(int id,String name) {
            return new ApiService(id,name);
        }
    }

@Module 注解的含义很简单,它就是告诉 Dagger 框架,这个类里面有可以提供对象创建的方法。所以 Module 类可以理解成一个用来组织对象创建方法的容器,关键是其内部的方法。

我的理解其实就是,生成bean对象的一个辅助类,相当于factory工厂类

注意:任何 Module 类的开头都以 @Module 进行注解。

@Inject

当注解一个属性的时候,表示该属性需要依赖(需要被注入一个对象)。
当注解一个构造函数的时候,表示该构造函数可以提供依赖。需要注意的是,如果被 @Inject 注解的构造函数是带参数的,比如这样:

inject_moudle.jpg
@Component

前面说了 @Module 提供依赖, @Inject请求依赖,而@Component 就是联系这两者的纽带。
Component 主要说明4件事:

谁来提供依赖
该 Component 依赖哪些其他的 Component
该 Component 为谁提供依赖注入
该 Component 可以提供那些依赖
@Component 注解的是一个接口,比如下面这个接口,表示它可以提供一个 MyApplication 类型的依赖。

对应前面说的4点:

  • module
    参数{}里的类就表示提供依赖的Module类(可以有多个),也就是用@Module
    注解的类
  • dependencies
    表示该 Component 提供的注入类的构造函数中,还依赖其他@Component
    提供的一些类。
  • 有参无反的方法指明该 Component 注入的目标,比如本例中,就说明 MyActivity 中需要 AppComponent 提供的依赖
  • 有反无参的方法指明该 Component 可以提供哪些依赖,或者说暴露哪些依赖。因为这里可能会有疑问,Component 可提供的依赖不就是 Module 里的那些吗?确实没错,但是 Component 也可以有选择的只对外界暴露它的一部分能力,并不一定会声明所有的在 Module 里定义的类。

这个接口可以理解成一份声明,告诉Dagger哪些对象可以被注入,以及谁(Module类中被@Provides
注解的方法)来提供这些依赖。需要注意,只有在 Component 接口中声明了的类,才会被暴露给依赖它的其他 Component。也就是说,Module 类中提供的依赖,并不一定都会在 Component 中声明。
最后,这个接口的实现会由 Dagger 框架自动生成,生成类的名字满足 *Dagger + 你的接口名
的格式。可以在 项目的app-buile
目录下找到生成的代码。后面的使用也主要是跟 Component 的实现类打交道。

我们来重新理一遍上面的注入过程,首先弄清楚以下几个概念:
@Inject 带有此注解的属性或构造方法将参与到依赖注入中,Dagger2会实例化有此注解的类
@Module 带有此注解的类,用来提供依赖,里面定义一些用@Provides注解的以provide开头的方法,这些方法就是所提供的依赖,Dagger2会在该类中寻找实例化某个类所需要的依赖。
@Component 用来将@Inject和@Module联系起来的桥梁,从@Module中获取依赖并将依赖注入给@Inject

参考注入的三种方式
对dagger2的解释挺好

Component--工厂管理员

注意

当module中创建对象的时候,需要传入参数的时候,需要添加传入参数的获取

参考ApiServiceModule类里面的代码

参考这里的解释
github项目地址

参考文档

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,133评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,682评论 3 390
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,784评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,508评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,603评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,607评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,604评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,359评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,805评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,121评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,280评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,959评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,588评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,206评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,442评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,193评论 2 367
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,144评论 2 352

推荐阅读更多精彩内容