最近在嘗試將兩個SDK集成到一個App中。這兩個SDK都是以aar格式提供的,在分別集成時均可以正常工做。但若是同時使用兩個SDK,編譯器會報告錯誤:java
Execution failed for task ':transformClassesWithJarMergingForDebug'. > com.android.build.api.transform.TransformException: java.util.zip.ZipException: duplicate entry: com/somewhere/over/the/Rainbow.class
原來這兩個SDK都使用了同一個jar包,並將其打包在aar中。android
使用gradle和com.android.application插件編譯Android工程時,gradle會將工程所依賴的aar包解壓縮到目錄api
build\intermediates\exploded-aar
每一個aar包獨佔一個子目錄。一般發生衝突的文件會保存在libs、jars、jni等幾個子目錄下。找到並刪除衝突文件,就能夠解決編譯問題。app
gradle可能會從新對aar進行解壓縮,所以手動刪除是不行的。觀察編譯的錯誤消息,編譯錯誤發生在任務transformClassesWithJarMergingForDebug中。只要爲它增長一個處理衝突的前置任務就好了。工具
task clearDuplicatedClasses { doFirst { def buildDir = project.getBuildDir() def files = ["\\intermediates\\exploded-aar\\MyAar\\jars\\libs\\Abc.jar", "\\intermediates\\exploded-aar\\MyAar\\jars\\libs\\Def.jar", "\\intermediates\\exploded-aar\\MyAar\\jars\\libs\\Xyz.jar"] files.each { delete new File(buildDir, it) } } } project.afterEvaluate { project.tasks.findByName("transformClassesWithJarMergingForDebug").dependsOn(clearDuplicatedClasses) }
transformClassesWithJarMergingForDebug是動態添加到project.tasks中的,若是直接寫成gradle
project.tasks.transformClassesWithJarMergingForDebug.dependsOn(clearDuplicatedClasses)
gradle會報告找不到任務。ui
若是咱們須要在已有的jar包(或SDK)上作一些封裝,並將封裝後的代碼做爲SDK提供給客戶。這時咱們能夠考慮構建兩個版本,一個只包含封裝層代碼,另外一個包含所有代碼。以避免出現jar包衝突的狀況,方便客戶使用。lua
若是想了解一個gradle任務依賴於哪些任務,可使用-dry-run(或-m)參數執行這個任務:spa
.\gradlew.bat -m assembleDebug
Android gradle plugin插件位於$home\.gradle\caches\modules-2\files-2.1\com.android.tools.build\gradle-core的子目錄下,名字是gradle-core-X.Y.Z.jar。這個jar包沒有混淆,可使用反編譯工具查看裏面的代碼。編譯Android工程使用的不少任務都定義在裏面。插件
使用gradle編譯時,不少任務是動態添加的。要了解有project包含了哪些任務,以及這些任務對應的類,能夠在build.gradle裏增長一個任務
task listAllTasks { doFirst { println("========================================") getProject().getTasks().forEach { task -> print(task.getName()) print("\t") println(task.getClass().getName()) } println("========================================") } }
若是要查看某個特定任務對應的類,能夠用
task printTaskClass { doFirst { println("========================================") println(getProject().getTasks().findByName("prepareDebugDependencies").getClass()) println("========================================") } }
2019年07月30日 創建文檔。