配置
在 module 下的 build.gradle 添加兩個依賴即可:
compile 'com.google.dagger:dagger:2.11'
annotationProcessor 'com.google.dagger:dagger-compiler:2.11'
網上有很多需要導入 apt,但是在 gradle 2.2 后自帶有 Annotation Processor 提供該功能。并且 apt 已經停止維護了,因此不需要用 apt ;
標簽
先了解標簽的作用,最后再總結整個依賴注入的過程和原理:
@Inject
構造方法和變量都要使用 @Inject 標簽。
@Component
創建一個 component 文件,類型只能是接口或者抽象類。例如:
@Component
public interface MyComponent {
void inject(MainActivity activity);
}
方法名和類名是什么無所謂,主要作用是聯系帶有 @Inject 標簽的構造方法和變量。
調用 Android Studio 菜單欄的 build ==> make project 后,會生成 DaggerMyComponent:
// 觸發 Dagger 機制
DaggerMyComponent.create().inject(this);
// 等價于 DaggerMyComponent.builder().build().inject(this);
@Module 和 @Provides
@Module 標簽的使用,是為了可以創建構造方法帶有第三方框架的類或自定義類對象參數的情況。
例如:public A (String str) {}
這樣我們就不能實例化成功。使用要和 @Component 和 @Provides 標簽一起用:
@Component(module = MyModule.class)
public interface MyComponent {
void inject(MainActivity activity);
}
@Module
public class MyModule{
@Provides
public B provideB() {
B b = new B("123456");
return b;
}
}
若是 Module 內的方法帶有參數,可以采用 module 的可傳遞性:
@Module
public class MyModule{
@Provides
public B provideB(String str) {
return new B(str);
}
@Provides
public String provideString() {
return "str";
}
}
@Named
為了區分可以多個實例,還有多個構造方法的情況,因此引用了 @Named 標簽,用戶區分。詳細使用如下:
public class MainActivity extends Activity {
@Named("TYPE_INT")
@Inject
public B bInt;
@Named("TYPE_STR")
@Inject
public B bStr;
}
@Component(Module = BModule.class)
public interface BComponent{
public void inject(MainActivity activity);
}
@Module
public class BModule {
@Named("TYPE_INT")
@Provides
public void provideBInt() {
return new B(132);
}
@Named("TYPE_STR")
@Provides
public void provideBStr() {
return new B("str");
}
}
自定義標簽
例如 @Named 標簽想自己定義一個:
@Qualifier
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface MySelf {
int value() default 1;
}
@Singleton
實現單例,但是只是針對同個 Component 的同個 inject 方法實現單例。使用方式如下:
@Singleton
@Component
public class MyComponent {}
@Module
public class MyModule {
@Singleton
@Provides
public A provideA() {
return new A();
}
}
@Scope
@Singleton 是 @Scope 的實現,通過 @Scope 可以自己寫個單例標簽。簡單說就是沒有 @Scope 標簽時,每次注入都會創建對象。
@Scope
@Documented
@Retention(RUNTIME)
public @interface Singleton {}
帶參數的構造方法
- 若是參數是個人創建定義的,則可以直接使用 @Component 標簽。因為 dagger 具有遞歸創建對象的功能。例如:
public class A{
@Inject
public A(B b) {
// ...
}
}
public class B{
@Inject
public B(){
// ...
}
}