一、概述
现在android开发越来越多的应用到各种框架,一个好的app架构不但可以支持好的性能,同时也可以更方便快捷的开发功能。依赖注入是java后端开发spring的核心技术,而对于android来说现在由谷歌爸爸亲管的dagger则是不二之选。
二、dagger环境配置
使用Android Studio 创建一个新的项目,在Project的 build.gradle文件添加以下内容:
buildscript {
dependencies {
// 顺便也配置了支持lambda表达式
classpath 'me.tatarka:gradle-retrolambda:3.2.4'
// classpath 'com.android.tools.build:gradle:3.0.1' 正常gradle插件配置
}
}
并在Module下的build.gradle添加以下内容:
apply plugin: 'me.tatarka.retrolambda'
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
annotationProcessor 'com.google.dagger:dagger-compiler:2.4'
compile 'com.google.dagger:dagger:2.4'
provided 'org.glassfish:javax.annotation:10.0-b28'
}
注意:使用新插件时,必须使用 annotationProcessor 依赖项配置将注解处理器添加到处理器类路径中。
三、dagger的注解
dagger的基本使用主要是通过各项注解来实现的,所以搞清楚常用注解的作用十分重要
- @Inject:有两个作用,1是在需要依赖的类(目标类,即宿主)中标记成员变量告诉Dagger这个类型的变量需要一个实例对象。2是标记类中的构造方法(一般为无参构造方法)告诉Dagger我可以提供这种类型的依赖实例。
- @Provides:用来提供依赖实例,对方法进行注解,且都是有返回类型的。用来告诉Dagger我们想如何创建并提供该类型的依赖实例(一般会在方法中new出实例)。用@Provides标记的方法,谷歌推荐采用provide为前缀,必须用在@Module注解的类中,方法所需的参数也需要以方法的形式返回提供。
- @Module:用来标记类(一般类名以Module结尾)。Module主要的作用是用来集中管理@Provides标记的方法。我们定义一个被@Module注解的类,Dagger就会知道在哪里找到依赖来满足创建类的实例。modules的一个重要特征是被设计成区块并可以组合在一起供@Component所注解的类使用。
- @Component:用来标记接口或者抽象类(一般以Component结尾),是@Inject(指第一个作用)和@Module之间的桥梁,主要职责是把二者组合在一起,Module中的实例对象必须在Component中暴露出来才能供之后使用。所有的components都可以通过它的modules知道它所提供的依赖范围。一个Component可以依赖一个或多个Component,并拿到被依赖Component暴露出来的实例,Component的dependencies属性就是确定依赖关系的实现。
- @Scope:作用域,Dagger2通过自定义注解来限定作用域,有一个默认的作用域注解@Singleton,通常在Android中用来标记在App整个生命周期内存活的实例。也可以自定义一个@PerActivity、@PerFragment注解,用来表明实例生命周期与Activity、Fragment一致。我们可以自定义作用域的粒度(比如@PerUser等等)。
- @Qualifier:限定符。当一个类的类型不足以标示一个依赖的时候,我们就可以用这个注解。例如,我们有两个@Provide注解的方法都需要一个String参数,那么在提供依赖的方法上面就可以通过自定义标识“@ForData”或者“@ForImage”来进行区别Dagger2里面已经存在一个限定符@Named注解,通过@Named(”xxxxx”)就可以进行标识。具体使用请看下方,十分简单明了。
- @SubComponent:如果我们需要父组件全部的提供对象,这时我们可以用包含方式而不是用依赖方式,相比于依赖方式,包含方式不需要父组件显式显露对象(依赖方式只能拿到暴露出的实例),就可以拿到父组件全部对象。且SubComponent只需要在父Component接口中声明就可以了。
四、dagger基本使用
1.通过@Inject、@Component实现依赖注入(最简单的方式):
提供一个依赖注入的对象,比如User
public class User {
private String name;
// 这个@Inject表示可以提供User类型的实例
@Inject
public User() {
this.name = "this is test";
}
public String getName() {
return name;
}
}
提供一个宿主,比如Activity
public class MainActivity extends AppCompatActivity {
@Inject
User user;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
注意:需要注意的是使用@Inject注解的变量不能是private变量,否则会报以下错误:Error:(13, 20) 错误: Dagger does not support injection into private fields
提供一个桥梁,即Component
<