配制dagger2開發環境
- 配制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自身需要的依賴,另一種是構建工程需要的依賴。
在buildscript下的dependencies結點添加gradle自身需要的依賴,如:
直接在dependencies結點下添加構建工程需要的依賴,如:
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'
的含意是,編譯時使用dagger-compiler,打包時不需要將dagger-compiler包打包到apk中。因為dagger2在編譯時根據注解生成相應代碼,所以在打包時沒有必要將不需要的三方包(dagger-compiler)打包到apk里。
這里說一下dagger-compiler與dagger的區別
- dagger-compiler.jar有8M左右,dagger.jar有27K左右
- dagger-compiler.jar是根據注解生成代碼的主體,dagger.jar里基本上只包含工廠類和注解類
- dagger-compiler.jar在編譯時使用,不需要打包到apk里;dagger.jar提供注解和抽象,需要打包到apk里
根據Dagger1的CoffeeSimple寫一個Dagger2程序
Dagger2有很多注解,而且可以自定義注解。本次任務是用最少的代碼寫出一個最小的程序。用到Module,Provides,Inject,Component,Singleton五個最基本的注解,以下是它們的簡單介紹:
- Module作用于類上,表明該是一個工廠類,產生各種活生生的類
- Provides作用于Module中的方法上,表示該方法可以提供一個類
- Singleton表示提供的類為單列
- Inject標記需要注入的變量
- Component作用于接口類上,使該類相當于一個紐帶,連接Module和需要注入實例的類(如:Activity)。就是將Module中生成的類注入(賦值)到Activity中使用Inject標記的變量上
由于CoffeeSimple是基于Dagger1寫的,主要意圖是將CoffeeMaker注入到CoffeeApp的coffeeMaker變量,是一個java程序。我們用Dagger2在android程序上重新演繹一下該過程,所以這個CoffeeApp.java類就沒有用了(用MainActivity.java代替)。看一下CoffeeSimple里的類
暫時先不管CoffeeApp,根據名字可以將它們簡單分一下類,其中Heater, ElectricHeater, Pump, Thermosiphon, CoffeeMaker屬于實體類(Model),DripCoffeeModule, PumpModule屬于提供類的工廠(Module)。
簡單建立一個android demo,結構如下:
接下來逐一介紹上面說到的五個注解在Dagger2Coffee中起到的作用
首先查看實體類的UML類圖,使用plantUML畫的,各類圖位置不好調整湊合著看吧。
從圖中可以看出model類中只使用了一個注釋Inject,分別標記了CoffeeMaker里的heater、pump字段、構造器和Thermosiphon的構造器,Inject作用之前已經提到了。
然后查看module的UML類圖,如下
這里看不出注解,因為我不知道如何使用plaintUml給類圖添加注解~~ 但是還是可以看出Module就是一個工廠類,只提供生成類的方法。現在進入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;
}
}
這里使用了三個注釋,Module、Provides、Singleton 它們各自的作用之前已經提到了。
基本的材料都已經做好了,接下來該使用了。
小插曲,用過ButterKnife的同學都應該知道以下代碼片段的作用
我們如何使用Dagger2達到同樣的效果呢,比如這樣
直接這樣肯定是不行的,因為ButterKnife是根據傳入的context定位到需要注入的字段mButton,然后通過資源加載器將實例賦值給mButton。ButterKnife能如此干凈利落的完成注入主要完成兩個操作:定位需要注入的view,通過資源加載器注入實例。Dagger2也需要這兩步操作才能像ButterKnife那樣優雅的完成注入,現在已經完成第一個操作(定位需要進入注入的字段),接下來完成第二個操作——添加“資源加載器”。其實我們已經寫好這個“資源加載器”了,就是之前寫的那兩個module類。但是如何把它們關聯起來呢?這時候該Component就出場了。
由于MainActivityComponent只是一個接口,這里直接給出它的源碼
//MainActivityComponent.class
@Singleton
@Component(modules = {DripCoffeeModule.class, PumpModule.class})
public interface MainActivityComponent {
void inject(MainActivity activity);
}
就是在這里activity與modules建立了聯系,當然這里只是定義的接口,但是通過dagger-compiler庫(配制dagger開發環境時配制好的)可以為該接口生成一個實現DaggerMainActivityComponent。activity與module有了聯系,module提供的實例自然可以注入到activity中需要注入的字段(用@Inject標記的字段)上。注意,每次編輯Component接口(如MainActivityComponent)時,apt會自動調用dagger-compile重新編譯DaggerComponent(如DaggerMainActivityComponent)。好了,現在可以使用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();
}
}
輸出
如果代碼沒有錯誤,但是沒有發現DaggerMainActivityComponent類時,重新build一下項目就可以了
如果想看一下DaggerMainActivityComponent或者查看由apt根據dagger-compile規則自動生成的代碼時,到這個目錄下去找
這個Demo只是最最基本的Dagger2的用法,還有很多高級用法自己慢慢體會吧。我相信只要入了門,其它的用的多了自然就會了。
咖啡煮完了,回家歇息吧... 這里是Dagger2Coffee源碼。
以下是擴展閱讀