将一个项目由eclipse转android studio时,由于该项目引用lib多达6、7个,一上手就碰到了引用包冲突的问题,问题描述如下
UNEXPECTED TOP-LEVEL EXCEPTION: com.android.dex.DexException: Multiple dex files define Landroid/support/v4/acce ssibilityservice/AccessibilityServiceInfoCompat$AccessibilityServiceInfoVersionI mpl; at com.android.dx.merge.DexMerger.readSortableTypes(DexMerger.java:579) at com.android.dx.merge.DexMerger.getSortedTypes(DexMerger.java:535) at com.android.dx.merge.DexMerger.mergeClassDefs(DexMerger.java:517) at com.android.dx.merge.DexMerger.mergeDexes(DexMerger.java:164) at com.android.dx.merge.DexMerger.merge(DexMerger.java:188) at com.android.dx.command.dexer.Main.mergeLibraryDexBuffers(Main.java:50 4) at com.android.dx.command.dexer.Main.runMonoDex(Main.java:334) at com.android.dx.command.dexer.Main.run(Main.java:277) at com.android.dx.command.dexer.Main.main(Main.java:245) at com.android.dx.command.Main.main(Main.java:106)
虽然这个问题在网上有很多类似解决的帖子,但均说的不全面详细,,我另外花了不少时间才把问题彻底解决,,在这里把经验分享出来。
第一步:
如果直接使用v4的jar包,gradle打包时,会将v4包打包进当前module,如果有引用该module的其它工程,会再将该module中的v4包再编译一次,导致v4包被打包多次,引起冲突。在对应项目的build目录下,你可以发现实实在在的存在多个v4包,只是它们的名字会多了一串sha1算法生成的字符串:
\build\intermediates\pre-dexed\official\debug
解决办法:在build.gradle中加入compile ‘com.android.support:support-v4:23.1.0’并删除libs目录下的v4包,这样可以避免多v4包的冲突问题(注意对应版本的V4包你是否下载,否则会另报错):
dependencies { compile fileTree(dir: 'libs', include: '*.jar') compile 'com.android.support:support-v4:23.1.0' }
如果第一步可以了,那恭喜你,下面的内容可以暂时忽略了(如果以后没有包冲突的问题)。
但一般引用lib库多,由eclipse转的时候并不一定能这样理想,所以如果还有冲突,请继续看第二步。
第二步
既然还有冲突,那就去找到实际冲突的文件是哪些。
首先打开项目的root目录,也就是项目文件夹同一级的目录,会有一些gradle project的基本配置,目录结构如下:
your project/ src/ res/ build/ build.gradle settings.gradle
打开build文件夹,定位到build\intermediates\dex-cache下,会有cache.xml这样一个文件。
它记录了你的项目中所有依赖的库的路径、版本信息、编译后存入的路径,如下:
<item jar="C:\tfs\you project\libs\android-support-v4.jar" jumboMode="false" revision="23.0.2" sha1="5896b0a4e377ac4242eb2bc785220c1c4fc052f4"> <dex dex="C:\tfs\your project\build\intermediates\pre-dexed\official\debug\android-support-v4_8d5ef003cbda980f7be9134c6bb7eb7a566626d2.jar" /> </item>
搜索其中的android-support-v4.jar,这些即是多余的引起冲突的包了,根据它提供的路径,找到并删除该jar。实际操作时,仅删除jar是不够的,由于gradle缓存文件的问题,上一次的编译可能已经将jar在build目录下编译了对应的文件,,所以直接将整个build目录删除了,避免缓存带来的删除jar不生效的问题。
这样再次编译应该就能解决v4包冲突的问题了。
如果存在其它类似的引用冲突的问题(基本上带Multiple dex的提示信息都是同一个问题),,也可以直接打开cache.xml,去定位问题。
gradle打包初次上手会有不少问题,,基本上找关键字build或gradle的目录或文件,分析一下应该会很容易找到解决方法。