配置
在 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(){
// ...
}
}
网友评论