用dagger2煮咖啡

配制dagger2開發(fā)環(huán)境

  • 配制project下的build.gradle
buildscript {  
     repositories {    
         jcenter()   
     }

    dependencies {        
        classpath 'com.android.tools.build:gradle:2.1.0'        
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'            
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files    
    }
}
  • 配制module下的build.gradle
  • 添加apt插件 apply plugin: 'com.neenbedankt.android-apt'
  • 添加dagger依賴
dependencies {
        ...
 
        apt 'com.google.dagger:dagger-compiler:2.5'    
        compile 'com.google.dagger:dagger:2.5'
}

說明:gradle中的依賴分為兩種:一種是gradle自身需要的依賴吠谢,另一種是構(gòu)建工程需要的依賴渴丸。
在buildscript下的dependencies結(jié)點(diǎn)添加gradle自身需要的依賴,如:

/Dagge2Coffee/build.gradle

直接在dependencies結(jié)點(diǎn)下添加構(gòu)建工程需要的依賴,如:
/Dagge2Coffee/app/build.gradle

apt是由android-apt插件提供的,添加android-apt插件的方法為 apply plugin: 'com.neenbedankt.android-apt' 其中apply plugin是gradle語法,所在包為'com.android.tools.build:gradle:2.1.0'即在buildscript-depenpendencs下classpath 'com.android.tools.build:gradle:2.1.0'引入的。添加android-apt插件后就可以使用apt命令了。apt 'com.google.dagger:dagger-compiler:2.5'的含意是蜕径,編譯時(shí)使用dagger-compiler,打包時(shí)不需要將dagger-compiler包打包到apk中败京。因?yàn)閐agger2在編譯時(shí)根據(jù)注解生成相應(yīng)代碼兜喻,所以在打包時(shí)沒有必要將不需要的三方包(dagger-compiler)打包到apk里。

這里說一下dagger-compiler與dagger的區(qū)別

  • dagger-compiler.jar有8M左右喧枷,dagger.jar有27K左右
  • dagger-compiler.jar是根據(jù)注解生成代碼的主體虹统,dagger.jar里基本上只包含工廠類和注解類
  • dagger-compiler.jar在編譯時(shí)使用弓坞,不需要打包到apk里;dagger.jar提供注解和抽象车荔,需要打包到apk里

根據(jù)Dagger1的CoffeeSimple寫一個(gè)Dagger2程序

Dagger2有很多注解渡冻,而且可以自定義注解。本次任務(wù)是用最少的代碼寫出一個(gè)最小的程序忧便。用到Module族吻,Provides,Inject珠增,Component超歌,Singleton五個(gè)最基本的注解,以下是它們的簡(jiǎn)單介紹:

  • Module作用于類上蒂教,表明該是一個(gè)工廠類巍举,產(chǎn)生各種活生生的類
  • Provides作用于Module中的方法上,表示該方法可以提供一個(gè)類
  • Singleton表示提供的類為單列
  • Inject標(biāo)記需要注入的變量
  • Component作用于接口類上凝垛,使該類相當(dāng)于一個(gè)紐帶懊悯,連接Module和需要注入實(shí)例的類(如:Activity)。就是將Module中生成的類注入(賦值)到Activity中使用Inject標(biāo)記的變量上

由于CoffeeSimple是基于Dagger1寫的梦皮,主要意圖是將CoffeeMaker注入到CoffeeApp的coffeeMaker變量炭分,是一個(gè)java程序。我們用Dagger2在android程序上重新演繹一下該過程剑肯,所以這個(gè)CoffeeApp.java類就沒有用了(用MainActivity.java代替)捧毛。看一下CoffeeSimple里的類

/CoffeeSimple/*.java

暫時(shí)先不管CoffeeApp让网,根據(jù)名字可以將它們簡(jiǎn)單分一下類呀忧,其中Heater, ElectricHeater, Pump, Thermosiphon, CoffeeMaker屬于實(shí)體類(Model),DripCoffeeModule, PumpModule屬于提供類的工廠(Module)溃睹。
簡(jiǎn)單建立一個(gè)android demo荐虐,結(jié)構(gòu)如下:
/Dagge2Coffee/app/src/main/java/rubo/dagge2coffee

接下來逐一介紹上面說到的五個(gè)注解在Dagger2Coffee中起到的作用
首先查看實(shí)體類的UML類圖,使用plantUML畫的丸凭,各類圖位置不好調(diào)整湊合著看吧。
model.puml

從圖中可以看出model類中只使用了一個(gè)注釋Inject腕铸,分別標(biāo)記了CoffeeMaker里的heater惜犀、pump字段、構(gòu)造器和Thermosiphon的構(gòu)造器狠裹,Inject作用之前已經(jīng)提到了虽界。
然后查看module的UML類圖,如下

module.puml

這里看不出注解涛菠,因?yàn)槲也恢廊绾问褂胮laintUml給類圖添加注解~~ 但是還是可以看出Module就是一個(gè)工廠類莉御,只提供生成類的方法∑餐蹋現(xiàn)在進(jìn)入module類里查看使用了什么注解

//DripCoffeModul.java

@Module
public class DripCoffeeModule {
    @Provides
    @Singleton
    Heater provideHeater() {
            return new ElectricHeater();
    }
}
//PumpModule.java

@Module
public class PumpModule {
        @Provides
        @Singleton
        Pump providePump(Thermosiphon pump) {
            return pump;
        }
}

這里使用了三個(gè)注釋,Module礁叔、Provides、Singleton 它們各自的作用之前已經(jīng)提到了涣易。
基本的材料都已經(jīng)做好了,接下來該使用了。
小插曲荚醒,用過ButterKnife的同學(xué)都應(yīng)該知道以下代碼片段的作用


sample

我們?nèi)绾问褂肈agger2達(dá)到同樣的效果呢铺董,比如這樣


sample2

直接這樣肯定是不行的重付,因?yàn)锽utterKnife是根據(jù)傳入的context定位到需要注入的字段mButton帽芽,然后通過資源加載器將實(shí)例賦值給mButton。ButterKnife能如此干凈利落的完成注入主要完成兩個(gè)操作:定位需要注入的view款票,通過資源加載器注入實(shí)例。Dagger2也需要這兩步操作才能像ButterKnife那樣優(yōu)雅的完成注入,現(xiàn)在已經(jīng)完成第一個(gè)操作(定位需要進(jìn)入注入的字段),接下來完成第二個(gè)操作——添加“資源加載器”埂伦。其實(shí)我們已經(jīng)寫好這個(gè)“資源加載器”了基跑,就是之前寫的那兩個(gè)module類荆秦。但是如何把它們關(guān)聯(lián)起來呢?這時(shí)候該Component就出場(chǎng)了。
由于MainActivityComponent只是一個(gè)接口,這里直接給出它的源碼
//MainActivityComponent.class

@Singleton
@Component(modules = {DripCoffeeModule.class, PumpModule.class})
public interface MainActivityComponent {
        void inject(MainActivity activity);
}

就是在這里activity與modules建立了聯(lián)系梁肿,當(dāng)然這里只是定義的接口烛芬,但是通過dagger-compiler庫(配制dagger開發(fā)環(huán)境時(shí)配制好的)可以為該接口生成一個(gè)實(shí)現(xiàn)DaggerMainActivityComponent遣臼。activity與module有了聯(lián)系性置,module提供的實(shí)例自然可以注入到activity中需要注入的字段(用@Inject標(biāo)記的字段)上。注意,每次編輯Component接口(如MainActivityComponent)時(shí)屏歹,apt會(huì)自動(dòng)調(diào)用dagger-compile重新編譯DaggerComponent(如DaggerMainActivityComponent)。好了霹崎,現(xiàn)在可以使用Dagger2煮咖啡了,代碼如下:

public class MainActivity extends AppCompatActivity {
        
        @Inject    
        CoffeeMaker mCoffeeMaker;
        
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            DaggerMainActivityComponent.builder()
                    .dripCoffeeModule(new DripCoffeeModule())
                    .pumpModule(new PumpModule())
                    .build().inject(this);
            mCoffeeMaker.brew();
        }
}

輸出

console output

如果代碼沒有錯(cuò)誤默赂,但是沒有發(fā)現(xiàn)DaggerMainActivityComponent類時(shí)沛鸵,重新build一下項(xiàng)目就可以了
rebuild path

如果想看一下DaggerMainActivityComponent或者查看由apt根據(jù)dagger-compile規(guī)則自動(dòng)生成的代碼時(shí)疾捍,到這個(gè)目錄下去找
/Dagger2Coffee/app/build/generated/source/apt/debug

這個(gè)Demo只是最最基本的Dagger2的用法,還有很多高級(jí)用法自己慢慢體會(huì)吧栏妖。我相信只要入了門乱豆,其它的用的多了自然就會(huì)了。
咖啡煮完了吊趾,回家歇息吧... 這里是Dagger2Coffee源碼宛裕。
以下是擴(kuò)展閱讀

更加強(qiáng)大的Dagger2

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市论泛,隨后出現(xiàn)的幾起案子揩尸,更是在濱河造成了極大的恐慌,老刑警劉巖孵奶,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件疲酌,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡了袁,警方通過查閱死者的電腦和手機(jī)朗恳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來载绿,“玉大人粥诫,你說我怎么就攤上這事≌赣梗” “怎么了怀浆?”我有些...
    開封第一講書人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)怕享。 經(jīng)常有香客問我执赡,道長(zhǎng),這世上最難降的妖魔是什么函筋? 我笑而不...
    開封第一講書人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任沙合,我火速辦了婚禮,結(jié)果婚禮上跌帐,老公的妹妹穿的比我還像新娘首懈。我一直安慰自己,他們只是感情好谨敛,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開白布究履。 她就那樣靜靜地躺著,像睡著了一般脸狸。 火紅的嫁衣襯著肌膚如雪最仑。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,182評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音盯仪,去河邊找鬼紊搪。 笑死,一個(gè)胖子當(dāng)著我的面吹牛全景,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播牵囤,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼爸黄,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了揭鳞?” 一聲冷哼從身側(cè)響起炕贵,我...
    開封第一講書人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎野崇,沒想到半個(gè)月后称开,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡乓梨,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年鳖轰,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片扶镀。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蕴侣,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出臭觉,到底是詐尸還是另有隱情昆雀,我是刑警寧澤,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布蝠筑,位于F島的核電站狞膘,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏什乙。R本人自食惡果不足惜挽封,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望稳强。 院中可真熱鬧场仲,春花似錦、人聲如沸退疫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽褒繁。三九已至亦鳞,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背燕差。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工遭笋, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人徒探。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓瓦呼,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親测暗。 傳聞我的和親對(duì)象是個(gè)殘疾皇子央串,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容