天天看點

gradle中compile、api、provided、implementation

一、gralde中compile,api,provided,implementation的差別:

  1. compile ‘com.android.support:appcompat-v7:23.4.0’
  2. provided ‘com.squareup.dagger:dagger-compiler:1.2.1’(網絡下載下傳)
  3. provided fileTree(include: ‘*.jar’, dir: ‘…/…/…/core/Base/Gdroid/libs’)(本地路徑)
  4. compile files(‘libs/picasso-2.4.0.jar’)
  5. compile project(’:androidPullToRefresh’)
  • compile是從repository(預設是jCenter())裡下載下傳一個依賴包進行編譯并打包。
  • provided隻提供編譯支援,但是不會寫入apk。比如我在編譯的時候對某一個jar檔案有依賴,但是最終打包apk檔案時,我不想把這個jar檔案放進去,可以用這個指令。
  • compile files是從本地的libs目錄下尋找picasso-2.4.0.jar這個檔案進行編譯并打包。類似的指令有

    compile fileTree(dir: 'libs', include: '*.jar')

    意思是将libs目錄下所有jar檔案進行編譯并打包。

    compile project是将另一個module

    (等同eclipse中的library庫檔案)進行編譯并打包。
  • api 指令 :完全等同于 compile指令,沒差別,你将所有的compile改成api,完全沒有錯。

注:gradle tools更新到3.0.0以上,compile關鍵字 已經明确寫明廢棄了(api關鍵字的作用等同于之前的compile),但是google官方文檔上說“還會保留一段時間,直到下個比較大的gradle tools版本釋出”。是以現在仍然使用compile,不會報錯。

implementation說明:

implementation指令:這個指令的特點就是,對于使用了該指令編譯的依賴,對該項目有依賴的項目将無法通路到使用該指令編譯的依賴中的任何程式,也就是将該依賴隐藏在内部,而不對外部公開。

implementation的“通路隔離”隻作用在編譯期

implementation的“通路隔離”隻作用在編譯期。什麼意思呢?如果lib C 依賴了lib A 2.0版本,lib B implementation依賴了lib A 1.0版本:

  • 那麼編譯期,libC 可通路2.0版本的libA

    ,libB可通路1.0版本的libA。但最終打到apk中的是2.0版本(通過依賴樹可看到)。

  • 在運作期,lib B 和lib C都可通路lib

    A的2.0版本(因為apk的所有dex都會放到classLoader的dexPathList中)。

使用implementation有什麼好處

  • 如果項目中有很多級聯的工程依賴,比如上圖中lib A B C的依賴是工程依賴。如果使用的依賴方式是compile/api,那麼當lib A接口修改後重新編譯時,會重新編譯libA B C(即使lib C中并沒有用到修改的libA的接口)。如果使用implementation依賴,因為“編譯期隔離”的原因,不相關的lib就不會進行重新編譯。
  • 如果項目中都是aar依賴,編譯減少時長這個優點就沒有了(因為aar已經是編譯好的位元組碼了)。那麼還有什麼用呢?還是以上圖為例。之前我們都是compile依賴,如果lib A已經依賴了lib B,那麼在libC的build.gradle中就不用寫lib A的依賴了。但這樣會有問題:
    1. 我從lib C的build.gradle的依賴清單中不能完整的知道libC都需要依賴哪些lib。
    2. 假設這麼一種情況,我知道項目中的依賴的libA的最高版本是2.0,那麼app運作時就是使用的這個2.0版本的libA。這時候我需要打一個libC的aar。lib C如果通過compile傳遞依賴了libA,是以從lib C的build.gradle中不知道lib C 編譯時依賴的是哪個版本的lib A。如果libC 打aar(編譯)時,依賴的仍然libA 1.0,可能這個aar就有問題了。

繼續閱讀