关于 Android Dex 方法限制的一些总结
原文地址:http://greenrobot.me/devpost/about-android-dex-method-number-limit/
Android的编译过程
在了解这个问题之前我们先要来看看Android 应用编译的过程:
-
IDE中的资源打包工具 (Android Asset Packaging Tool ,即图中的aapt) 会将应用中的资源文件进行编译,这些资源文件包括
AndroidManifest.xml
文件,为Activity定义的 XML 文件等等。在这个编译过程中也会产生一个R.java
文件,这样你就可以在你的Java代码中引用这些资源了。 -
aidl 工具会将你项目中的所有
.aidl
接口转换成Java接口。 -
项目中的所有的Java代码,包括
R.java
和.aidl
文件,都会被Java编译器编译,然后输出 .class 文件。 -
接着 dex 工具就会把上一步骤产生的 .class 文件转成 Dalvik 字节码,也就是
.dex
文件。同时项目中包含的所有第三方类库和 .class 文件也会被转换成.dex
文件,这样讲方便下一步被打包成最终的.apk
文件。 -
所有的不能编译的资源(比如图片等等)、编译后的资源文件和 .dex 文件会被 apkbuilder 工具打包成一个
.apk
文件。 -
一旦
.apk
文件被构建好之后,如果要把把它安装到设备上面去的话,它就必须用一个debug 或者发行key来对这个apk文件签名。 -
最后,如果应用程序已经被签名成为发行模式的apk,你还需要使用 aipalign工具对
.apk
进行对齐优化。这样的话可以减少应用程序在设备上的内存消耗。
为什么会有这个Dex 方法限制
内部原因:
我们注意到在第四步的时候,会产生一个.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的半壁江山。
那么如何解决Android Dex 方法限制这个问题呢?
老方法
对于内部原因:
-
从上面的描述中我们知道,Android Dex 方法限制是出现在单个
.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://developer.android.com/tools/building/index.html
- http://android-developers.blogspot.com/2011/07/custom-class-loading-in-dalvik.html
- https://medium.com/@rotxed/dex-skys-the-limit-no-65k-methods-is-28e6cb40cf71
- http://developer.android.com/tools/building/multidex.html
- jakewharton.com/play-services-is-a-monolith/
- http://www.keysolutions.com/blogs/kenyee.nsf/d6plinks/KKYE-9LP5ND
- http://www.alittlemadness.com/2010/06/07/understanding-the-android-build-process/
- http://source.android.com/devices/tech/dalvik/dalvik-bytecode.html
- http://stackoverflow.com/questions/21490382/does-the-android-art-runtime-have-the-same-method-limit-limitations-as-dalvik/21492160#21492160
- https://android.googlesource.com/platform/dalvik/+/froyo/vm/analysis/ReduceConstants.c
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。