1. 程式人生 > >安卓工程依賴方式:Implementation vs API dependency

安卓工程依賴方式:Implementation vs API dependency

升級到 Android studio 3.0版本會使多Module工程的構建速度加快很多。不幸的是,這也帶來了Gradle 外掛版本API的較大變化。本文將會詳細指出這個變化帶來的好處,並且指導讀者怎麼去升級。
ps: Android plugin 3.0.0搭配Gradle 3.4版本以上

  • 問題現狀

為了理解老版本Gradle plugin 2.0構建系統的限制,這裡假設有個工程使用了多層module依賴方式。請看下圖。

project結構圖
對於最底部的基礎module,其將會有兩種可能的變化:
1. Implementation 變化:不會改動本module對外暴露的介面。
2. Application binary interface (ABI) 變化:將會改變本module對外暴露的介面

本module指的是呼叫dependency的module

注意,所有需要重新編譯的module將會用紅色標出。

  • Implementation 變化
    當本module依賴的ib(也可以是module)發生變化時,由於本module對外暴露的介面並不發生變化,在構建工程時gradle將會只重新編譯本module,所有依賴於本module的module並不會發生編譯。這種情況是沒什麼問題的。如圖所示。
    project_implementation.png

  • ABI變化
    當本module依賴的ib(也可以是module)發生變化時,本module向外暴露的介面發生了變化,那麼所有直接依賴於本module的module將不得不重新編譯。

project_gradle_2.0_step1.png
接下來,這些上層module可能通過其本身的介面對外暴露了底層module的部分內容,即意味著本module暴露的介面也發生了變化,這會使得依賴於上層module的上上層module也需要重新編譯。這就導致了一個連鎖效應,因此,為了絕對的安全起見,gradle將不得不重新編譯整個工程,使得編譯時間變得較長。如圖所示。

project_gradle_2.0_final.png

那麼重點來了:一點程式碼的改動可能會引起整個工程的重新編譯,這將是多麼悲催,而實際上我們之前的gradle外掛2.0版本系列的確如此,根本原因就是gradle壓根不知道暴露的介面可以通過一個接一個的依賴傳遞影響整個工程。

  • Android Gradle plugin 3.0帶來了解決方案

    最新版的Gradle plugin需要你指出一個module的介面是否對外暴露其依賴lib的介面。基於此,可以讓專案構建時,gradle可以判斷哪個需要重新編譯。因此,老版本的構建關鍵字compile被廢棄了,而是改成了這兩個:
  • api:同compile作用一樣,即認為本module將會洩露其依賴的module的內容。
  • implementation:本module不會通過自身的介面向外部暴露其依賴module的內容。
    由此,我們可以明確的告訴gradle去重新編譯一個module,若是這個使用的module的介面發生變化的話。
dependencies {
//當legofy介面發生變化時,需要重新編譯本module以及所有使用本modulemodule
api project(':legofy') 
// 僅當landscapevideocamera發生變化時,重新編譯本module
implementation project(':landscapevideocamera:1.0.0')
}
  • 遷移指南
    理論上,你可以將原來工程中的compile完全替換為現在的api,但是一旦依賴發生變化,將會使所有的module重新編譯,造成編譯過長。

所以更好的方式就是使用implementation來進行依賴,這會大大改善工程的構建時間。只有你明確要向外部暴露所依賴lib的介面時,才需要使用api依賴,整體來說,會減少很多重新編譯。這一點,在官方指南中說的比較明確。

翻譯人: 劉鹹尚

  • 其它的變化
    既然有了比較大的改變,索性官方團隊利用此機會改了更多配置屬性的名字,
    比如provided改成了compileOnly,apk改成了runtimeOnly

大體如上,詳情可參考官方遷移指南