dagger2笔记

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

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

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

参考博客:

  1.     https://my.oschina.net/u/994565/blog/702385
  2.     http://blog.csdn.net/wds1181977/article/details/51822043

 

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

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

完整代码如下:

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可以代替传统的对代码信息和附属文件的维护工作。

 

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

@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这个类是就是自动生成的。

 

未完待续

转载于:https://my.oschina.net/u/3038281/blog/814100

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值