原文地址:http://greenrobot.me/devpost/about-android-dex-method-number-limit/
在了解这个问题之前我们先要来看看Android 应用编译的过程:
AndroidManifest.xml
文件,为Activity定义的
XML 文件等等。在这个编译过程中也会产生一个 R.java
文件,这样你就可以在你的Java代码中引用这些资源了。.aidl
接口转换成Java接口。R.java
和 .aidl
文件,都会被Java编译器编译,然后输出
.class 文件。.dex
文件。同时项目中包含的所有第三方类库和
.class 文件也会被转换成 .dex
文件,这样讲方便下一步被打包成最终的 .apk
文件。.apk
文件。.apk
文件被构建好之后,如果要把把它安装到设备上面去的话,它就必须用一个debug 或者发行key来对这个apk文件签名。.apk
进行对齐优化。这样的话可以减少应用程序在设备上的内存消耗。
我们注意到在第四步的时候,会产生一个.dex
文件。Android 从之前的Dalvik 到现在Android
5.0 默认的ART 运行时环境都能够执行这个.dex
文件,它们还使用同一套指令集,即Dalvik 指令集。通过这篇关于Android
指令集格式的介绍文章中,我可以知道Dalvik 指令集是使用16位寄存器来保存项目中所有的方法引用,包括第三方的方法:
invoke-kind {vC, vD, vE, vF, vG}, meth@BBBB B: method reference index (16 bits)
这就意味着 Android的单个.dex
文件最能引用65536个方法,在这之后的方法就无法引用了。这就是Android
Dex 方法限制异常出现的原因,同时因为ART和Dalvik使用同一套指令集,这个限制在ART 运行时环境中也会存在。
第三方库里面包含太多的方法。这里就拿Google Play Service和Guava来举例。很多Android开发者都会用到Google Play Service库和Guava库,而你知道它们提供了多少了方法吗?Google Play Service 5.0里面就差不多包含了将近20k+方法,Guava提供了将近14k个方法。这个两个库就将近占了方法限制数目65536的半壁江山。
对于内部原因:
.dex
文件中的,那么我们可以在一个apk中使用多个.dex
文件吗?可以,Android
官方博客就给出了这个方案。(在Android5.0之前,由于大部分使用的是Dalvik 运行时环境,Dalvik 运行时环境限制一个apk只能包含一个classes.dex文件。)对于外部原因:
主要思路:使用multidex
support library 让Android5.0之前的版本也能在一个apk里面包含多个.dex
文件。具体使用方法请参看这篇文章。
Google不仅在工具上面做出了改进,还把自己的Google Play Service库也做了一番改动——从Google Play Service 6.5开始开始支持更细精度的依赖管理,也就是说你只需要Google Drive的api,而不需要google game,maps或者wallet等api的支持,那你就可以只引入Google Drive的api即可。这样可以在很大程度上减少Dex 方法限制出现的几率。
参考链接:
原文地址:http://blog.csdn.net/iamzp2008/article/details/41684433