Dagger 入門
Dagger簡(jiǎn)介
Dagger2是Google提供的依賴注入框架配名,依賴注入為Android中組件之間的解耦提供了很好的解決方案。 使用它可以自動(dòng)生成創(chuàng)建依賴關(guān)系所需要的代碼晋辆。減少很多模板化的代碼渠脉,更易于測(cè)試,降低耦合瓶佳,創(chuàng)建可復(fù)用可互換的模塊芋膘。已經(jīng)在越來越多的開源項(xiàng)目中被使用,其已經(jīng)發(fā)展成為未來的一個(gè)技術(shù)趨勢(shì)霸饲。
Dagger中基礎(chǔ)注釋解釋
@Inject:翻譯為注入为朋,該注解在javax包中,不是Dagger獨(dú)有的注解厚脉,在Dagger中作用于構(gòu)造方法和字段中潜腻,作用在構(gòu)造方法中會(huì)解析生成一個(gè)類的工廠模板對(duì)象,表示提供該類的實(shí)例器仗,作用在字段中表示創(chuàng)建一個(gè)對(duì)象得到一個(gè)對(duì)象實(shí)例融涣。
@Component:翻譯為組件,在Dagger中@Component的作用就是關(guān)聯(lián)精钮,比如我們Activity中需要一個(gè)Goods商品對(duì)象威鹿,而如果只用
@Inject是不行的,因?yàn)?br>
@Inject作用在Goods的構(gòu)造方法中的時(shí)候轨香,只是提供了一個(gè)工廠類忽你,而作用在Acivity的字段也只是告訴解釋器Activity需要這個(gè)對(duì)象卻沒有進(jìn)行關(guān)聯(lián)操作,@Component會(huì)為程序生成一個(gè)提供Activity和Goods工廠類相關(guān)聯(lián)的管道的類臂容。沒有Component編輯的時(shí)候不會(huì)報(bào)錯(cuò)科雳,但是對(duì)象肯定是null的。
@Module:模塊脓杉,作用在類中糟秘,是為了解決@Inject的局限性而Dagger加入的獨(dú)有注解,也是為生成對(duì)象而生的球散,他配合@Provides使用尿赚,還有就是用來區(qū)分模塊,比如網(wǎng)絡(luò)、db凌净、Sp等都有自己需要生成的類悲龟,我們總能放在一個(gè)類中吧,他跟@Provides是一對(duì)多的關(guān)系冰寻,@Provides不能脫離他實(shí)現(xiàn)须教,否則會(huì)報(bào)錯(cuò)。
@Provides:提供類斩芭,只能作用在方法中轻腺,不能作用在沒有@Module注解的類的方法中,否則會(huì)報(bào)錯(cuò):Error:(18, 18) 錯(cuò)誤: @Provides methods can only be present within a @Module or @ProducerModule秒旋,其作用跟@Inject一樣也是生成工廠類。
基本概念
Dagger 是通過@Inject使用具體的某個(gè)對(duì)象诀拭,這個(gè)對(duì)象呢迁筛,是由@Provides注解提供,但是呢耕挨,這個(gè)@Provides只能在固定的模塊中细卧,也就是@Module注解,我們查找的時(shí)候筒占,不是直接去找模塊贪庙,而是去找@Component
如何使用Dagger
引入依賴庫
//在項(xiàng)目的build.gradle文件中添加
compile 'com.google.dagger:dagger:2.11'
annotationProcessor 'com.google.dagger:dagger-compiler:2.11'
創(chuàng)建Module
@Module
public class MainModule {
}
創(chuàng)建具體的示例
public class A{
public void eat(){
Log.e("wyl","吃飯");
}
//第一步 添加@Module 注解
@Module
public class MainModule {
//第二步 使用Provider 注解 實(shí)例化對(duì)象
@Provides
A providerA() {
return new A();
}
創(chuàng)建一個(gè)Component
//第一步 添加@Component
//第二步 添加module
@Component(modules = {MainModule.class})
public interface MainComponent {
//第三步 寫一個(gè)方法 綁定Activity /Fragment
void inject(MainActivity activity);
}
Rebuild Project
然后AS 會(huì)自動(dòng)幫我們生成
將Component與Activity/Fragment綁定關(guān)系
package com.allens.daggerdemo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import com.allens.daggerdemo.Bean.A;
import com.allens.daggerdemo.component.DaggerMainConponent;
import javax.inject.Inject;
public class MainActivity extends AppCompatActivity {
/***
* 第二步 使用Inject 注解翰苫,獲取到A 對(duì)象的實(shí)例
*/
@Inject
A a;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/***
* 第一步 添加依賴關(guān)系
*/
//第一種方式
DaggerMainConponent.create().inject(this);
//第二種方式
DaggerMainConponent.builder().build().inject(this);
/***
* 第三步 調(diào)用A 對(duì)象的方法
*/
a.eat();
}
}
以上為Dagger的簡(jiǎn)單使用止邮,有人肯定會(huì)說為了在activity中獲取到A對(duì)象,繞這么一個(gè)大彎太麻煩了奏窑,如果在多個(gè)類中引用了A對(duì)象导披,按照之前的方式獲取A對(duì)象的引用得通過new A()來獲取,如果A類構(gòu)造函數(shù)對(duì)應(yīng)有變化埃唯,是不是引用A類的每個(gè)類都得做相應(yīng)修改撩匕,如果用Dagger來管理對(duì)象,減低耦合度墨叛,避免牽一發(fā)而動(dòng)全身止毕。