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這個類是就是自動生成的。

 

未完待續

相關文章
相關標籤/搜索