最近在尝试将两个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日 创建文档。