1. 程式人生 > >當使用Gralde編譯出現某jar包或庫重複依賴的各種解決方案

當使用Gralde編譯出現某jar包或庫重複依賴的各種解決方案

這是半年前做專案時遇到的問題,因為專案有好幾個依賴庫,其中有個庫的httpmime這個jar包在多個地方重複出現了,最終編譯打包的時候報錯對同一個jar包重複打包了,試了各種方法都無效,花了兩三天才找到一個方法,用三行程式碼搞定,因為時間過了比較久所以可能記得也不是很清楚,只能憑印象記錄下來,有錯誤的麻煩看到的朋友提出指正。

1.

compile fileTree(dir: 'libs', include: '*.jar', exclude:'android-support-v4.jar') 

這種方法適用於在主專案中排除libs目錄下的v4等重複包,由於依賴庫中已有這些包所以即使排除了也不會出現異常,exclude標籤也可以用於排除具體依賴庫中的每個依賴,但是於我當時的情況下不適用,具體原因忘了

2.設定依賴的scope,這點gradle類似於maven,這裡貼上maven的scope含義說明,更具體的有興趣的可以查資料和驗證,具體的設定方式即在build.gralde中更改每項依賴的前面識別符號,如compile,或者通過設定module的dependency也可

依賴範圍控制哪些依賴在哪些classpath 中可用,哪些依賴包含在一個應用中。讓我們詳細看一下每一種範圍:

compile (編譯範圍) 

compile是預設的範圍;如果沒有提供一個範圍,那該依賴的範圍就是編譯範圍。編譯範圍依賴在所有的classpath 中可用,同時它們也會被打包。

provided (已提供範圍)

provided 依賴只有在當JDK 或者一個容器已提供該依賴之後才使用。例如, 如果你開發了一個web 應用,你可能在編譯classpath 中需要可用的Servlet API 來編譯一個servlet,但是你不會想要在打包好的WAR 中包含這個Servlet API;這個Servlet API JAR 由你的應用伺服器或者servlet 容器提供。已提供範圍的依賴在編譯classpath (不是執行時)可用。它們不是傳遞性的,也不會被打包。 

runtime (執行時範圍) 

runtime 依賴在執行和測試系統的時候需要,但在編譯的時候不需要。比如,你可能在編譯的時候只需要JDBC API JAR,而只有在執行的時候才需要JDBC 驅動實現。 test (測試範圍) test範圍依賴 在一般的編譯和執行時都不需要,它們只有在測試編譯和測試執行階段可用。

system (系統範圍) 

system範圍依賴與provided 類似,但是你必須顯式的提供一個對於本地系統中JAR 檔案的路徑。這麼做是為了允許基於本地物件編譯,而這些物件是系統類庫的一部分。這樣的構件應該是一直可用的,Maven 也不會在倉庫中去尋找它。如果你將一個依賴範圍設定成系統範圍,你必須同時提供一個 systemPath 元素。注意該範圍是不推薦使用的(你應該一直儘量去從公共或定製的 Maven 倉庫中引用依賴)。

3.中間還有找到過其他方法,但是都不行,而且時間過了太久忘記了,這裡貼上最後使用的方法:
android.libraryVariants.all { variant ->
	variant.outputs.each { output ->
		output.packageLibrary.exclude(libs/httpmime-4.2.2.jar)
	}
}
那時候有和另一位網上的開發人員討論,這種方法被認為是干涉gradle的生命週期裡,修改正常的配置項和配置結果,然後影響下一步執行階段的操作和結果,沒記錯的話這句話只能在com.android.library外掛下才可使用