配制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自身需要的依賴,如:
直接在dependencies結(jié)點(diǎn)下添加構(gòu)建工程需要的依賴,如:
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里的類
暫時(shí)先不管CoffeeApp让网,根據(jù)名字可以將它們簡(jiǎn)單分一下類呀忧,其中Heater, ElectricHeater, Pump, Thermosiphon, CoffeeMaker屬于實(shí)體類(Model),DripCoffeeModule, PumpModule屬于提供類的工廠(Module)溃睹。
簡(jiǎn)單建立一個(gè)android demo荐虐,結(jié)構(gòu)如下:
接下來逐一介紹上面說到的五個(gè)注解在Dagger2Coffee中起到的作用
首先查看實(shí)體類的UML類圖,使用plantUML畫的丸凭,各類圖位置不好調(diào)整湊合著看吧。
從圖中可以看出model類中只使用了一個(gè)注釋Inject腕铸,分別標(biāo)記了CoffeeMaker里的heater惜犀、pump字段、構(gòu)造器和Thermosiphon的構(gòu)造器狠裹,Inject作用之前已經(jīng)提到了虽界。
然后查看module的UML類圖,如下
這里看不出注解涛菠,因?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)該知道以下代碼片段的作用
我們?nèi)绾问褂肈agger2達(dá)到同樣的效果呢铺董,比如這樣
直接這樣肯定是不行的重付,因?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();
}
}
輸出
如果代碼沒有錯(cuò)誤默赂,但是沒有發(fā)現(xiàn)DaggerMainActivityComponent類時(shí)沛鸵,重新build一下項(xiàng)目就可以了
如果想看一下DaggerMainActivityComponent或者查看由apt根據(jù)dagger-compile規(guī)則自動(dòng)生成的代碼時(shí)疾捍,到這個(gè)目錄下去找
這個(gè)Demo只是最最基本的Dagger2的用法,還有很多高級(jí)用法自己慢慢體會(huì)吧栏妖。我相信只要入了門乱豆,其它的用的多了自然就會(huì)了。
咖啡煮完了吊趾,回家歇息吧... 這里是Dagger2Coffee源碼宛裕。
以下是擴(kuò)展閱讀