本文翻譯于 Bedanta Bikash Borah 的文章皮璧,原文鏈接如下:
當(dāng)我們?cè)贏ndroid項(xiàng)目中使用 Gradle 3.0 及以上版本的插件,你一定會(huì)注意到 compile
關(guān)鍵字已經(jīng)被棄用來(lái)支持 implementation
和 api
诉稍。讓我們借助一個(gè)例子來(lái)了解它們。
示例應(yīng)用 (Kotlin) 可以在這里找到界睁。
讓我們假設(shè)有一個(gè) Android 項(xiàng)目包含以下四個(gè) library module:
- LibraryA
- LibraryB
- LibraryC
- LibraryD
它們之間的依賴關(guān)系如下所示:
每個(gè) Library module 都包含一個(gè)簡(jiǎn)單的類球昨。
LibraryD:
class ClassD {
fun tellMeAJoke():String{
return "You are funny :D"
}
}
LibraryC:
class ClassC {
fun tellMeAJoke(): String {
return "You are funny :C"
}
}
LibraryB:
class ClassB {
val b = ClassD()
fun whereIsMyJoke(): String {
return b.tellMeAJoke()
}
}
LibraryA:
class ClassA {
val c = ClassC()
fun whereIsMyJoke(): String {
return c.tellMeAJoke()
}
}
從上面這些類文件中可以看到 LibraryA 和 LibraryB 分別依賴于 LibraryC 和 LibraryD辕近。因此封孙,需要將它們之間的依賴關(guān)系添加到 build.gradle
文件當(dāng)中迹冤。
Compile (2.0) or Api (3.0):
3.0 中新的 api
關(guān)鍵字與之前版本的 compile
關(guān)鍵字意義完全相同。因此虎忌,如果項(xiàng)目中所有 compile
關(guān)鍵字被 api
所取代泡徙,這完全可以正常工作。現(xiàn)在膜蠢,讓我們?cè)?LibraryB 中通過(guò) api
關(guān)鍵字來(lái)依賴 LibraryD:
dependencies {
. . . .
api project(path: ':libraryD')
}
同樣地堪藐,將 LibraryB 添加到 app 模塊中:
dependencies {
. . . .
api project(path: ':libraryB')
}
現(xiàn)在,我們可以在 app 模塊中訪問(wèn)到 LibraryB 和 LibraryD挑围。在示例應(yīng)用中礁竞,兩個(gè)庫(kù)的訪問(wèn)形式如下:
Implementation (3.0):
現(xiàn)在是時(shí)候來(lái)找出 implementation
和 api
之間的不同之處了。再次回到上面這個(gè)例子杉辙,現(xiàn)在讓我們?cè)?LibraryA 中通過(guò) implementation
關(guān)鍵字引入 LibraryC:
dependencies {
. . . .
implementation project(path: ':libraryC')
}
App 模塊同理:
dependencies {
. . . .
implementation project(path: ':libraryA')
}
現(xiàn)在模捂,如果我們?cè)?app 模塊訪問(wèn) LibraryC,Android studio 將會(huì)拋出一個(gè)錯(cuò)誤:
這意味著如果我們使用 implementation
關(guān)鍵字代替 api
蜘矢,LibraryC 將無(wú)法在 App 模塊中被訪問(wèn)狂男。那么 implementation
這樣做有什么好處呢?
Implementation vs api:
在第一個(gè)場(chǎng)景中品腹,LibraryD 是通過(guò) api
關(guān)鍵字來(lái)編譯的岖食。一旦 LibraryD 中的實(shí)現(xiàn)做了任何改動(dòng),那么 gradle 都需要重新編譯 LibraryD珍昨,LibraryB 和所有其他引入 LibraryB 的模塊一樣可能使用的是 LibraryD 中的實(shí)現(xiàn)县耽。
但在第二個(gè)場(chǎng)景中,如果更改了 LibraryC 中的代碼實(shí)現(xiàn)镣典,那么 Gradle 只會(huì)重新編譯 LibraryC 和 LibraryA,因?yàn)槠渌魏螞](méi)有直接依賴 LibraryC 的類都無(wú)法使用其中任何實(shí)現(xiàn)唾琼。
如果你正在開(kāi)發(fā)具有多個(gè)模塊的項(xiàng)目兄春,那么這種策略可以顯著加快構(gòu)建過(guò)程。我在示例程序中進(jìn)行了嘗試锡溯,幾秒鐘后就有了一些改進(jìn)赶舆。以下是所有方案的構(gòu)建報(bào)告。
全量構(gòu)建:
變更 LibraryD:
變更 libraryC
總結(jié)
Android Gradle 插件版本升級(jí)至3.0之后祭饭,我們只需要將所有 compile
替換為 implementation
關(guān)鍵字并嘗試構(gòu)建項(xiàng)目芜茵。如果可以構(gòu)建成功,那么很好倡蝙。否則九串,請(qǐng)查找任何你可能正在使用的遺漏的依賴庫(kù),并找到宿主 library 換用 api
關(guān)鍵字引入這些 library。