Android "multiple dex files define" 错误

原创
2015/08/31 11:07
阅读数 968

Android开发中经常看到这个错误,产生的原因还是挺值得研究的。

 

如果是在eclipse上出现的这个问题,基本上可以判断为同一工程中存在相同的jar包,或者是不同的jar包,但是他们之间有相同的类,所以解决办法就是干掉对方。 eclipse中如果删除jar之后还报错的话,可能是eclipse的缓存导致的,重启eclipse基本可以解决这个问题。

 

但是如果事情发生在 Android Studio 上,那么就复杂了。首先要排除eclipse中的那种情况,如果问题还没有解决那就要仔细了。

 

如果工程结构是这样的

 

  tree root

root

├── project1

   └── libs

       └── abc.jar

└── project2

    └── libs

        └── abc.jar

这样的结构还是很常见的,比如很多时候libs下面放的是android-support-v4.jar,如果这个两个工程中只有一个依赖 abc.jar 那么删掉不用的那个问题解决。

 

但是通常的情况可能是这两个工程确实都各自的需要 abc.jar ,那么问题就棘手了(个人认为是ASbug),每个工程都需要,但是一编译就报错。

 

我的一个直觉想法是建立一个共享的 project3 专门用来存放共享的jar包,于是结构变成这样,

 

tree root 

root

├── project1 //depends on project3

   └── libs

├── project2 //depends on project3

   └── libs

└── project3

    └── libs

        └── abc.jar

但是这样编译之后却引起了更多的 "multiple dex files define" 问题,原因是project1project2 因为依赖project3的缘故,在编译阶段会把 abc.jar 拷贝到自己的工程下面,这样的结果是这三个工程都互相引起了jar包冲突。

 

一番Google百度之后给出的结论是这样的

 

If you have a local jar or aar library that you want to use in more than one project, you cannot just reference it directly as a local dependency. This is because the android plugin will complain if it finds the same jar file twice when dexing the project and all its dependencies. (Note that right now you can't actually use a local aar file even if you only reference it once).

来自于 Android Studio的官网 说明,也就是说在用 Android Studio 的时候最好就不要这么用了。

 

但是依然提供了一个方案

 

One way to fix this is to deploy the artifact in a repository. While it's possible, it might not be convenient due to the overhead of managing such a repository.

这个方案的意思就是如果你把jar包放在一个repo里面就可以直接引用了,但是管理repo很麻烦,比如我们经常用的 compile 'com.android.support:support-v4:21.0.0' 这句话就是从repojcenter)中拿到我们需要的jar包(所以如果重复的是support-v4包,那么直接改成这样就已经解决问题了)。

 

但是如果是一些私有的jar包,放到repo中也很麻烦,不太现实。还是Google给的方案,依然采用这样的结构,但是稍作修改

 

tree root 

root

├── project1 //depends on project3

   └── libs

├── project2 //depends on project3

   └── libs

└── project3

    └── libs

        └── abc.jar

project3build.gradle 文件中添加下面两句

 

dependencies {

    compile fileTree(dir: 'libs', include: ['*.jar'])

}

artifacts.add("default", file('abc.jar'))

把我们要用的jar包作为project3的输出包(具体原因不解)。

 

PS:原因是这样的每个工程依赖的是另外工程的输出也就是“artifacts”,这里的操作是强制把abc.jar添加为这个工程的输出包。建议可以使用爱内测对APP进行一个全方位的测试:http://www.ineice.com/


展开阅读全文
打赏
0
21 收藏
分享
加载中
更多评论
打赏
0 评论
21 收藏
0
分享
返回顶部
顶部