不多說直接上一張表格
| gradle3 | gradle2 | 說明 |
|---|---|---|
| implementation | compile | 依賴項(xiàng)在編譯時(shí)對(duì)模塊可用,并且僅在運(yùn)行時(shí)對(duì)模塊的消費(fèi)者可用。 對(duì)于大型多項(xiàng)目構(gòu)建,使用 implementation 而不是 api/compile 可以顯著縮短構(gòu)建時(shí)間,因?yàn)樗梢詼p少構(gòu)建系統(tǒng)需要重新編譯的項(xiàng)目量。 大多數(shù)應(yīng)用和測(cè)試模塊都應(yīng)使用此配置。 |
| api | compile | 依賴項(xiàng)在編譯時(shí)對(duì)模塊可用,并且在編譯時(shí)和運(yùn)行時(shí)還對(duì)模塊的消費(fèi)者可用。 此配置的行為類似于 compile(現(xiàn)在已棄用),一般情況下,您應(yīng)當(dāng)僅在庫模塊中使用它。 應(yīng)用模塊應(yīng)使用 implementation,除非您想要將其 API 公開給單獨(dú)的測(cè)試模塊。 |
| compileOnly | provided | 依賴項(xiàng)僅在編譯時(shí)對(duì)模塊可用,并且在編譯或運(yùn)行時(shí)對(duì)其消費(fèi)者不可用。 此配置的行為類似于 provided(現(xiàn)在已棄用) |
| runtimeOnly | apk | 依賴項(xiàng)僅在運(yùn)行時(shí)對(duì)模塊及其消費(fèi)者可用。 此配置的行為類似于 apk(現(xiàn)在已棄用) |
第一列是gradle3新Api,第二列為gradle重的api,并且將要在Gradle為5的軟件版本重移除。
看到這里,你也許會(huì)疑惑。如何區(qū)分implementation,api以及compile呢?
如何區(qū)分implementation,api以及compile
首先api和compile是同一個(gè)東西,那么只需要分辨他們和implementation的區(qū)別。一張圖來說明

假如我們的工程是如上所示的依賴關(guān)系,如果使用Compile方式進(jìn)行依賴,修改紅色模塊,需要編譯所有洋紅色的模塊。相比之下使用Implentation方式進(jìn)行依賴,只需要編譯兩個(gè)青色的模塊。從而大幅度提高編譯速度。
理想是豐滿的,實(shí)際開發(fā)中,項(xiàng)目依賴混亂,完全使用Implentation非常困難,尤其是一些公共模塊,基本每一模塊都會(huì)用到。那么只能使用api模塊進(jìn)行依賴。當(dāng)修改使用api進(jìn)行依賴的模塊的時(shí)候,任何依賴他的模塊都可以引用他的方法。舉個(gè)例子:

第二行第二個(gè)使用api的方式依賴紅色模塊。任何洋紅色模塊都可以引用紅色模塊的方法,換言之當(dāng)紅色模塊修改的時(shí)候,所有洋紅色模塊都會(huì)重新編譯。所以api只適用經(jīng)常不改動(dòng)的模塊,方便其他模塊進(jìn)行引用。
在我們的項(xiàng)目中,抽離compile依賴是很頭疼的一件事,在接下來的文檔中會(huì)提到。
所以:
-
Implentation通常項(xiàng)目之間的依賴,這個(gè)要求我們項(xiàng)目之間要做好解耦。 -
Api不經(jīng)常改動(dòng)的項(xiàng)目,可以使用他進(jìn)行依賴。
分辨運(yùn)行時(shí)依賴和編譯時(shí)依賴
在講compileOnly和runtimeOnly之前,先弄清什么是么是運(yùn)行時(shí)依賴和編譯時(shí)依賴。
顧名思義,從名稱上理解他的意思其實(shí)是正確的。
- 編譯時(shí)候(coding)的依賴就是編譯時(shí)依賴
- 運(yùn)行時(shí)候(building)的依賴就是運(yùn)行時(shí)依賴
(此時(shí)停頓一下,好好理解)
但是實(shí)際項(xiàng)目中錯(cuò)綜復(fù)雜:還是使用一張圖來說明:

思考一下,D模塊那三個(gè)版本號(hào)是多少呢?
答案是根本編譯不過去。
但是這張圖理解這個(gè)概念已經(jīng)夠了,首先,針對(duì)B模塊,編譯時(shí)依賴是gson2.6,support升級(jí)22,okhttp是3;其他也是這么理解。
如果單獨(dú)運(yùn)行C模塊是運(yùn)行不過去的,你需要需要指定這三個(gè)以來的版本號(hào),解決版本依賴沖突。這就是運(yùn)行時(shí)依賴。有很多種方式解決這種重復(fù)依賴的方法,比如force或者exclude。
compileOnly和runtimeOnly
- compileOnly 指的是在coding時(shí)候進(jìn)行依賴,實(shí)際打包時(shí)候,不打入aar,同時(shí)他也不報(bào)錯(cuò)。
compileOnly經(jīng)常會(huì)用于子模塊,比如A模塊要提供對(duì)B模塊的支持,同時(shí)又不能引入B模塊(主工程已經(jīng)引用了),就會(huì)用到它。舉個(gè)例子:假如項(xiàng)目中用到了Retrofit,我們都知道Retrofit對(duì)Rx是有支持的,但是他并不包含Rx包。在編譯Retrofit代碼時(shí)候,就要用到compileOnly了,編譯時(shí)引用Rx,實(shí)際不打如包中。注意錯(cuò)誤使用可能會(huì)找不到類。 - runtimeOnly 和compileOnly相反,運(yùn)行時(shí)候才會(huì)打包進(jìn)去,編譯時(shí)候不提供。
compileOnly和runtimeOnly都提供對(duì)子模塊的使用,也就是說,在透?jìng)饕蕾嚪矫?,他們和api是一致的。
變體依賴
Gradle3 中提供了變體依賴,他是基于風(fēng)味維度的。比如xxxImplentation,我們項(xiàng)目中沒有用到,詳情了解,移步gradle官網(wǎng),簡(jiǎn)單說一下把: 比如項(xiàng)目工程有一個(gè)模塊AdModule,名為廣告模塊,在北美市場(chǎng)接入FB,印度市場(chǎng)接入獵豹,國(guó)內(nèi)接百度。那么就可以定義風(fēng)味維度為FB,Liebao,Baidu。在主工程進(jìn)行依賴的時(shí)候,如果打印度包,只需更改依賴為LieBaoImplentation,那么AdModule就是獵豹廣告的風(fēng)味維度,其他毅然。
如果你注意過,在使用buildType時(shí)候也可以這樣指定,比如 debugImplentation。
之前我們控制渠道信息,都是放到build.gradle的mainfestholder中,然后子項(xiàng)目進(jìn)行讀取,if else切換。風(fēng)味依賴倒是給了一個(gè)很好的解決方案,個(gè)人維護(hù)起來比較麻煩,這東西主項(xiàng)目和子項(xiàng)目維度匹配起來是個(gè)難題。。。適合大項(xiàng)目。