
Android 團隊在 Android Studio 3.0 中給我們帶來了非常多的改變,連帶著com.android.tools.build:gradle
工具也升級到了3.0.0,在3.0.0中使用了最新的Gralde 4.0 里程碑版本作為gradle的編譯版本,該版本gradle編譯速度有所加速,更加欣喜的是,完全支持Java8。當(dāng)然,對于Kotlin的支持,在這個版本也有所體現(xiàn),Kotlin插件默認(rèn)是安裝的。還有一點就是對項目依賴方式的改進。
通過創(chuàng)建一個新的工程,查看app Module中的依賴:
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support:design:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
……
}
經(jīng)常添加依賴使用的compile不見了,而現(xiàn)在改變?yōu)?code>implementation了。
原來在3.0版本中,compile 指令被標(biāo)注為過時方法,而新增了兩個依賴指令,一個是implementation和api,這兩個都可以進行依賴添加。
這種變化所帶來的改變就是在Android studio 3.0中建立多模塊項目的速度有了質(zhì)的飛躍,但這樣的改變也導(dǎo)致了對舊有Gradle plugin API的改變。
1. Gradle plugin 2.0的一些問題
讓我們來考慮這樣的一種情況:一個 App 工程往往是由許多互相依賴的 module 所組成

對于處于最底層、最基礎(chǔ)的那些 module,我們可以有兩種變化方法:
- Implementation change:internal change, doesn’t modify the external interface of the module
這是一種內(nèi)部的變化,但并不改變模塊的外部接口- Application binary interface (ABI) change:modify the external interface of the module
對外部接口進行了修改
1.1 Implementation change
因為模塊外部接口并沒有發(fā)生改變,Gradle只會重新編譯那些發(fā)生變化了的module, 而其他依賴它的 module 則不會重新編譯。

這種情況下不存在問題。
1.2 ABI change
在ABI情況下,由于模塊的外部接口發(fā)生了改變,所有依賴了該 module 的其他 module 都需要重新編譯。

但是這些模塊可能會通過他們自己的接口從而暴露出底層部分。所以安全起見,他們也需要被重新編譯。
因此Gradle不得不需要重新編譯所有的模塊。

從中我們發(fā)現(xiàn)了問題所在:一行修改,處處recompile。而導(dǎo)致這些的問題所在就是Gradle不知道m(xù)odule有沒有通過接口而導(dǎo)致泄露。這就使得編譯時間變長了。
2. Android Gradle plugin 3.0所帶來的改進
Android Gradle plugin 3.0就要求我們明確定義模塊接口是否存在泄露問題?;诮o出的定義它就可以對何時重新編譯做出正確的選擇。
基于此,過去常用的compile被標(biāo)記為過時并棄用,取而代之的就是api和implementation:
api: you leak the interface of this module through your own interface, meaning exactly the same as the old compile dependency(你可能通過這個模塊的接口造成泄露,其實和舊有的
compile相同)implementation: you only use this module internally and does not leak it through your interface(你只在內(nèi)部使用這個模塊且不會泄露接口)
所以,我們可以為特定 module 選擇 implementation 關(guān)鍵字來加快 gradle 構(gòu)建速度。
dependencies {
// recompile this module and all modules using this one
// when legofy interface is modified
api project(':legofy')
// only recompile this module when landscapevideocamera interface is modified
implementation project(':landscapevideocamera:1.0.0')
}
3. 遷移
最簡單的遷移其實就是把所有的compile換成api,當(dāng)然這么做其實沒什么變化,所有的Gradle依舊要重新編譯。
好的做法是將其都換成implementation,只在存在泄露風(fēng)險的地方使用api。
4. 其他參數(shù)
除了以上最大的改進,這次3.0也帶來以其他的一些變化:
- provided:configuration is now
compileOnly - apk:configuration is now
runtimeOnly