1. 程式人生 > 其它 >關於gradle的implementation、api和compileOnly三種依賴方式

關於gradle的implementation、api和compileOnly三種依賴方式

技術標籤:androidandroidgradle安卓

  • implementation: 參與編譯和打包,依賴的包不對其它工程開放
  • api : 參與編譯和打包,依賴的包對其它工程開放
  • compileOnly: 參與編譯但不參與打包,依賴的包對其它工程不開放。如果整個工程緊使用comileOnly方式依賴某個包,在使用時編譯不報錯,但執行的時候會找不到該類。如果有其它moudle使用了implementation或者api 方式依賴,那麼執行時就不會報錯,最終依賴的是其它module所匯入的包

一 場景主工程app依賴於moduleB,moduleB依賴於Gson包,在app當中呼叫Gson的方法

app:

implementation project(path: ':B')

方式一:B使用implementation依賴:

 implementation 'com.google.code.gson:gson:2.6.2'

效果:在工程A中呼叫Gson方法會編譯不通過

在這裡插入圖片描述

  • 結論:implementation不對外提供依賴的包,參與編譯打包

方式二:B使用api依賴:

 api 'com.google.code.gson:gson:2.6.2'

效果:app中呼叫Gson方法正常編譯並且執行

在這裡插入圖片描述

  • 結論:api對外提供工程所依賴的包,並且參與編譯和打包

方式三:B使用compileOnly依賴:

compileOnly 'com.google.code.gson:gson:2.6.2'
  • 結論:如方式一一樣編譯不通過,說明工程B依賴的Gson不對外開放,compileOnly不對外提供依賴的包

二 場景app使用compileOnly方式依賴Gson,注:此時工程A沒有依賴B

app:

compileOnly 'com.google.code.gson:gson:2.6.2'

在工程A當中使用Gson

在這裡插入圖片描述

編譯正常通過,打包執行找不類:

在這裡插入圖片描述

  • 結論:compileOnly參與編譯不參與打包

問題一:app依賴於B並使用compileOnly依賴Gson包,同時B中使用implementation依賴Gson包,在app當中使用Gson,那麼效果怎樣?

效果:正常編譯和執行

app使用了compileOnly方式依賴了Gson包,Gson參與了編譯,所以app當中使用Gson能夠正常編譯

那麼為何能夠正常執行呢?

B當中使用implementation方式依賴了Gson,雖然在編譯時不提供對外依賴給app,但打包時將Gson打包到了apk中,所以app執行時可以找到Gson包,故執行不報錯

思考,compileOnly存在的意義?

我們在使用第三方包的時候經常面臨包衝突的問題,如果我們提供包給別人用,如何來避免使用人員的包衝突問題呢?

同樣以Gson包為例,如果我們指定了我們module的Gson包版本為2.6.1使用如下兩種方式依賴

//    implementation 'com.google.code.gson:gson:2.6.1'
//        api 'com.google.code.gson:gson:2.6.1'

那麼使用我們module開發人員,也依賴了一個 Gson包,版本為2.6.2

//    implementation 'com.google.code.gson:gson:2.6.2'
//        api 'com.google.code.gson:gson:2.6.2'

這樣一來就打包執行時,apk當中就存在了兩個gson包,不但使apk體積增大,還可能造成app執行報錯

如何避免?

如果我們有一種方式,在我們寫自己的moudle時能夠正常呼叫Gson包但不指定版本,具體版本由使用者來指定,這樣就能避免最終app當中Gson版本不同的問題,compileOnly佔位依賴的方式正好滿足這一需求