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这个类是就是自动生成的。
未完待续