dagger2笔记

dagger2是一个依赖注入框架,依赖注入框架主要用于模块间解耦,提升代码的健壮性和可维护性。android

官方简介:https://google.github.io/dagger/git

本文示例完整代码(官方代码整理到一个工程里):github

参考博客:app

  1.     http://www.javashuo.com/article/p-nfuvxjuj-kv.html
  2.     http://blog.csdn.net/wds1181977/article/details/51822043

 

在Android Studio工程下的根目录的build.gradle文件里加入框架

classpath 'com.neenbedankt.gradle.plugins:android-apt:1.7'

完整代码以下:ide

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.2.0'
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.7'
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}
allprojects {
    repositories {
        jcenter()
    }
}
task clean(type: Delete) {
    delete rootProject.buildDir
}

 

在须要用到dagger2的模块里添加函数

apply plugin: 'com.neenbedankt.android-apt'
apt 'com.google.dagger:dagger-compiler:2.8'
compile 'com.google.dagger:dagger:2.8'

完整代码以下:工具

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

android {
    compileSdkVersion 24
    buildToolsVersion "25.0.1"
    defaultConfig {
        applicationId "android.daggerexamples.google.googleexamples"
        minSdkVersion 9
        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'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })

    apt 'com.google.dagger:dagger-compiler:2.8'
    compile 'com.google.dagger:dagger:2.8'

    compile 'com.android.support:appcompat-v7:24.2.1'
    testCompile 'junit:junit:4.12'
}

 

APT(Annotation processing tool) 是一种处理注释的工具,它对源代码文件进行检测找出其中的Annotation,使用Annotation进行额外的处理。Annotation处理器在处理Annotation时能够根据源文件中的Annotation生成额外的源文件和其它的文件(文件具体内容由Annotation处理器的编写者决定),
APT还会编译生成的源文件和原来的源文件,将它们一块儿生成class文件.使用APT主要的目的是简化开发者的工做量,由于APT能够编译程序源代码的同时生成一些附属文件(好比源文件类文件程序发布描述文件等),这些附属文件的内容也都是与源代码相关的,换句话说,使用APT能够代替传统的对代码信息和附属文件的维护工做。gradle

 

dagger2主要注解有:@Modules,@Provide,@Scope,@Qualifier,@Inject,@Component,ui

@Module:

  1. Modules类里面的方法专门提供依赖,因此咱们定义一个类,用@Module注解,这样Dagger在构造类的实例的时候,就知道从哪里去找到须要的 依赖。modules的一个重要特征是它们设计为分区并组合在一块儿(好比说,在咱们的app中能够有多个组成在一块儿的modules)。

@Inject:

  1. 一般在须要依赖的地方使用这个注解。换句话说,你用它告诉Dagger这个类或者字段须要依赖注入。这样,Dagger就会构造一个这个类的实例并知足他们的依赖。
  2. @Inject标记的成员变量会以调用了@Component的inject(x)方法后初始化实例,初始化顺序以下
    public interface ApplicationComponent {
      void inject(DemoApplication application);//必定要是具体的类,不能是父类。
      void inject(HomeActivity homeActivity);
      void inject(DemoActivity demoActivity);
    }
  3. 有两种方式能够提供依赖,一个是注解了@Inject的构造方法,一个是在Module里提供的依赖,那么Dagger2是怎么选择依赖提供的呢,规则是这样的:

  •         步骤1:查找Module中是否存在建立该类的方法。
  •         步骤2:若存在建立类方法,查看该方法是否存在参数
  •         步骤2.1:若存在参数,则按从步骤1开始依次初始化每一个参数
  •         步骤2.2:若不存在参数,则直接初始化该类实例,一次依赖注入到此结束
  •         步骤3:若不存在建立类方法,则查找Inject注解的构造函数,看构造函数是否存在参数
  •         步骤3.1:若存在参数,则从步骤1开始依次初始化每一个参数
  •         步骤3.2:若不存在参数,则直接初始化该类实例,一次依赖注入到此结束

​​​

@Provide: 在modules中,咱们定义的方法是用这个注解,以此来告诉Dagger咱们想要构造对象并提供这些依赖。

@Module
public class AndroidModule {
  @Provides @Singleton LocationManager provideLocationManager() {
    return (LocationManager) application.getSystemService(LOCATION_SERVICE);
  }
}

 

@Component:

  1. Components从根本上来讲就是一个注入器,也能够说是@Inject和@Module的桥梁,它的主要做用就是链接这两个部分。 Components能够提供全部定义了的类型的实例,好比:咱们必须用@Component注解一个接口而后列出全部的@Modules组成该组件,如 果缺失了任何一块都会在编译的时候报错。全部的组件均可以经过它的modules知道依赖的范围。

@Scope:

    Scopes但是很是的有用,Dagger2能够经过自定义注解限定注解做用域。

@Scope
@Retention(RUNTIME)
public @interface PerActivity {}

Qualifier:

     当类的类型不足以鉴别一个依赖的时候,咱们就可使用这个注解标示。例如:在Android中,咱们会须要不一样类型的context,因此咱们就能够定义 qualifier注解“@ForApplication”和“@ForActivity”,这样当注入一个context的时候,咱们就能够告诉 Dagger咱们想要哪一种类型的context。

 

dagger2官方简单的例子:一个Module,一个Component,而后使用依赖注入初始化@Inject注解的成员变量

@Qualifier @Retention(RUNTIME)
public @interface ForApplication {
}
@Module
public class AndroidModule {
  private final DemoApplication application;

  public AndroidModule(DemoApplication application) {
    this.application = application;
  }

  /**
   * Allow the application context to be injected but require that it be annotated with
   * {@link ForApplication @Annotation} to explicitly differentiate it from an activity context.
   */
  @Provides @Singleton @ForApplication Context provideApplicationContext() {
    return application;
  }

  @Provides @Singleton LocationManager provideLocationManager() {
    return (LocationManager) application.getSystemService(LOCATION_SERVICE);
  }
}

上面的类用@Module声明了一个Module,而且用@Provides声明了这个Module能提供注入LocationManager和Context实例。

 

public class DemoApplication extends Application {
  
  @Singleton
  @Component(modules = AndroidModule.class)
  public interface ApplicationComponent {
    void inject(DemoApplication application);
    void inject(HomeActivity homeActivity);
    void inject(DemoActivity demoActivity);
  }
  
  @Inject LocationManager locationManager; // for some reason.
  
  private ApplicationComponent component;

  @Override public void onCreate() {
    super.onCreate();
    component = DaggerDemoApplication_ApplicationComponent.builder()
        .androidModule(new AndroidModule(this))
        .build();
    component().inject(this); // As of now, LocationManager should be injected into this.
  }

  public ApplicationComponent component() {
    return component;
  }
}

@Component声明了一个ApplicationComponent,而且void inject(xxx),声明只能在DemoApplication,HomeActivity,DemoActivity几个类的实例里注入。

component = DaggerDemoApplication_ApplicationComponent.builder() .androidModule(new AndroidModule(this)) .build();这是构建了一个ApplicationComponent实例,

component().inject(this),调用这一句后,会初始化并给@Inject声明的 LocationManager locationManager对象初始化值。

 

DaggerDemoApplication_ApplicationComponent类不是咱们手动新建的,是自动生成的。

使用Android Studio 的Build->Make Project/Make Module '模块名',会看到自动生成了如下代码

 

DaggerDemoApplication_ApplicationComponent这个类是就是自动生成的。

 

未完待续

相关文章
相关标签/搜索