前言
Dagger2是目前非澈倨冢火的依賴注入框架,但是很多慕名而來的學(xué)者總感覺門檻高芒澜,很復(fù)雜,主要還是網(wǎng)上的很多教程比較復(fù)雜创淡,沒有做到由淺到深的講解痴晦。本篇將會一步一步的實現(xiàn)Dagger2。
一.Dagger2簡介
Dagger2是一個依賴注入框架琳彩,通過注解的方式減少手寫過多new對象的代碼誊酌,并做到充分的解耦,維護代碼更便利露乏。不僅能減少代碼量碧浊,就算構(gòu)造器發(fā)生變化,使用的地方也不需要做什么變化瘟仿。
還有一點要著重提下箱锐,Dagger2不是基于反射來實現(xiàn)的,Dagger1的原理是反射實現(xiàn)猾骡,所以Dagger2的性能更好瑞躺,但是靈活性會差點,沒有反射就沒有動態(tài)機制兴想。
二.Dagger2使用
1.配置
build.gradle中加入以下配置幢哨,最新版本以官方為準
implementation 'com.google.dagger:dagger:2.16'
annotationProcessor 'com.google.dagger:dagger-compiler:2.16'
2.簡單使用
首先新建一個類,并加上@Inject注解嫂便,該注解其實就是做標記
public class Person {
@Inject
public Person() {
}
public String sayHahaha(){
return "hahaha";
}
}
再新建Component注入器捞镰。需要注意的是inject()方法體的參數(shù)不能重復(fù)(即只能編寫一個參數(shù)為MainActivity的注入器),這里是給MainActivity編寫的注入器
@Component
public interface MainActivityComponent {
void inject(MainActivity activity);
}
然后build一次項目毙替,目的是生成對應(yīng)的DaggerMainActivityComponent類岸售。
注入器的使用如下,@Inject標記的作用就顯示出來了厂画,就是為了新建Person對象
public class MainActivity extends AppCompatActivity {
@Inject
Person person;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DaggerMainActivityComponent.create().inject(this);
person.sayHahaha();
}
}
3.有參構(gòu)造函數(shù)的使用
對于帶參構(gòu)造的對象凸丸,必須使用@Module注入;并且這個模型必須有一個帶參的構(gòu)造方法袱院。@Provides帶參提供者也是缺一不可的
@Module
public class Student {
private String name;
public Student() {
}
public Student(String name) {
this.name = name;
}
@Provides
public Student buildStudent(String name){
return new Student(name);
}
@Provides
public String getName() {
return name;
}
}
在原來注入器的基礎(chǔ)上面加上modules = Student.class
@Component(modules = Student.class)
public interface MainActivityComponent {
void inject(MainActivity activity);
}
然后build項目屎慢,然后直接使用就行
@Inject
Student student;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LoadUtils.bindView(this);
MainActivityComponent.builder().student(new Student("111")).build().inject(this);
student.getName();
}
4.不同構(gòu)造函數(shù)的使用
在調(diào)用一個類的時候可能會用到不同的構(gòu)造器,可以用@Named方式來進行區(qū)分
@Module
public class Student {
private String name;
public Student() {
}
public Student(String name) {
this.name = name;
}
@Provides
@Named("noName")
public Student buildStudent(){
return new Student();
}
@Provides
@Named("hasName")
public Student buildStudent(String name){
return new Student(name);
}
@Provides
public String getName() {
return name;
}
}
使用的時候也用相同的方式區(qū)分
@Named("hasName")
@Inject
Student student;
@Named("noName")
@Inject
Student student2;
由于用Name的形式不夠嚴謹忽洛,這里我們更多用到自定義注解的方式腻惠,用到@Qualifier
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface HasNameCons {
}
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface NoNameCons {
}
就可以直接這么使用,不太了解自定義注解的可以參考http://www.reibang.com/p/9d20a7391057
@Provides
@NoNameCons
public Student buildStudent(){
return new Student();
}
@Provides
@HasNameCons
public Student buildStudent(String name){
return new Student(name);
}
結(jié)語
Dagger2無論是中大型項目都很適用欲虚,代碼簡潔集灌,方便維護。本篇沒有特別貼出注入器構(gòu)建的代碼复哆,有興趣的可以自己研究下欣喧,比較簡單腌零。