转载请注明出处:http://my.csdn.net/Android___vv
Dagger2简称依赖注入,是实现程序解耦的一种方式。
大致原理:在程序中,一个对象中需要另一个对象的实例,实例对象的方式不再该对象中通过new
创建,而是调用者外部创建实例化对象,通过一定的方式进行传入。
上面所说的外部,指的就是一个存放对象的容器,具体需要哪个实例时,就从这个容器中取就行了。那么,现在类的实例和使用就不在有联系了,而是通过一个容器将他们联系起来。实现了解耦。这个容器,便是Dagger2
。
在工程的build.gradle
文件中添加android-apt
插件
dependencies {
classpath 'com.android.tools.build:gradle:2.1.0'
// 添加android-apt 插件
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
}
在app的中的
build.gradle
文件中添加配置
// 添加应用插件
apply plugin: 'com.neenbedankt.android-apt'
// dagger 2 的配置
compile 'com.google.dagger:dagger:2.4'
apt 'com.google.dagger:dagger-compiler:2.4'
compile 'org.glassfish:javax.annotation:10.0-b28'// 添加java 注解库
以上两个配置就可以了,但如果你的Studio
升级到3.0之后就会遇到
Error:android-apt plugin is incompatible with the Android Gradle plugin. Please use 'annotationProcessor' configuration instead.
解决办法:
Studio升级到3.0之后原来的配置方式apt与最新版本Gradle已经不兼容,推荐使用annotationProcessor
只需要添加这三个依赖就可以 工程的build.gradle与app的build.gradle插件可不用添加
// dagger 2 的配置
compile 'com.google.dagger:dagger:2.4'
annotationProcessor 'com.google.dagger:dagger-compiler:2.4'
compile 'org.glassfish:javax.annotation:10.0-b28'// 添加java 注解库
@Module //提供依赖对象的实例
public class MainModule {
@Provides
//标明该方法提供依赖对象
Person providerPerson(){
return new Person();
}
}
Component沟通部分 桥梁
@Component(modules = MainModule.class) // 作为桥梁,沟通调用者和依赖对象库
public interface MainComponent {
//定义注入的方法
void inject(MainActivity activity);
}
需要实例化对象的类中
public class MainActivity extends AppCompatActivity {
@Inject //标明需要注入的对象
Person person;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 构造桥梁对象
MainComponent component = DaggerMainComponent.builder().mainModule(new MainModule()).build();
//注入
component.inject(this);
}
}
public class MainActivity extends AppCompatActivity {
@Inject //标明需要注入的对象
Person person;
@Inject
Person person2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 构造桥梁对象
MainComponent component = DaggerMainComponent.builder().mainModule(new MainModule()).build();
//注入
component.inject(this);
//调用方法
person.get();
//打印地址
Log.i("TAG","person = "+ person.toString());
Log.i("TAG","person2 = "+ person2.toString());
}
}
下面是打印结果
01-10 18:45:41.623 6069-6069/com.example.dagger2 I/TAG: person = com.example.dagger2.Person@4a7f7928
01-10 18:45:41.623 6069-6069/com.example.dagger2 I/TAG: person2 = com.example.dagger2.Person@4a7f79c8
打印出的地址不同,也就是我们创建了两个对象,这时就用到了单利注解
Module中在提供实例化对象的方法上添加@Singleton
注解
@Singleton//单利注解
@Component(modules = MainModule.class) // 作为桥梁,沟通调用者和依赖对象库
public interface MainComponent {
//定义注入的方法
void inject(MainActivity activity);
}
MainComponent
也一样
@Singleton//单利注解
@Component(modules = MainModule.class) // 作为桥梁,沟通调用者和依赖对象库
public interface MainComponent {
//定义注入的方法
void inject(MainActivity activity);
}
再看一下打印结果
01-10 18:45:41.623 6069-6069/com.example.dagger2 I/TAG: person = com.example.dagger2.Person@4a7f7928
01-10 18:45:41.623 6069-6069/com.example.dagger2 I/TAG: person2 = com.example.dagger2.Person@4a7f7928
两个对象地址一样,只创建了一个对象,需要注意的是
@Singleton
只对一个
Component
有效,即其单例所依赖
Component
对象
需要实例化的类,构造方法需要传入一个集合
public class Person {
private List list;
public Person(List list) {
this.list = list;
}
public void get(){
Log.i("TAG",list.size()+"");
}
}
Module中
@Module //提供依赖对象的实例
public class MainModule {
private List mlist;
public MainModule(List list) {
this.mlist = list;
}
@Provides
List providesList(){
return mlist;
}
@Provides//标明该方法提供依赖对象
@Singleton//单利注解
Person providerPerson(List list){
return new Person(list);
}
}
providerPerson
方法,传入List
集合。providesList()
,用以提供List
集合。MainModule
中根据返回值,找到providerPerson(List list)
对象。List
,找到moudule
中具有返回值为List
的方法providesList()
。List
获取发生变化时,需要修改providerPerson(List list)
中的代码。Component中没有做改变
@Singleton//单利注解
@Component(modules = MainModule.class) // 作为桥梁,沟通调用者和依赖对象库
public interface MainComponent {
//定义注入的方法
void inject(MainActivity activity);
}
使用
import javax.inject.Inject;
public class MainActivity extends AppCompatActivity {
@Inject //标明需要注入的对象
Person person;
@Inject
Person person2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
List list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
list.add("数据"+i);
}
// 构造桥梁对象
MainComponent component = DaggerMainComponent.builder().mainModule(new MainModule(list)).build();
//注入
component.inject(this);
//调用方法
person.get();
}
}