dagger2是一個依賴注入框架,依賴注入框架主要用於模塊間解耦,提升代碼的健壯性和可維護性。android
官方簡介:https://google.github.io/dagger/git
本文示例完整代碼(官方代碼整理到一個工程裏):github
參考博客:app
在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:
@Inject:
public interface ApplicationComponent { void inject(DemoApplication application);//必定要是具體的類,不能是父類。 void inject(HomeActivity homeActivity); void inject(DemoActivity demoActivity); }
有兩種方式能夠提供依賴,一個是註解了@Inject的構造方法,一個是在Module裏提供的依賴,那麼Dagger2是怎麼選擇依賴提供的呢,規則是這樣的:
@Provide: 在modules中,咱們定義的方法是用這個註解,以此來告訴Dagger咱們想要構造對象並提供這些依賴。
@Module public class AndroidModule { @Provides @Singleton LocationManager provideLocationManager() { return (LocationManager) application.getSystemService(LOCATION_SERVICE); } }
@Component:
@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這個類是就是自動生成的。
未完待續