这一章是在继续学习android多dex之前必须要准备的知识
作为一个android开发者,在开发应用时,随着业务规模发展到一定程度,不断地加入新功能、添加新的类库,代码在急剧的膨胀,相应的apk包的大小也急剧增加, 那么终有一天,你会不幸遇到这个错误:
- 生成的apk在android 2.3或之前的机器上无法安装,提示INSTALL_FAILED_DEXOPT
- 方法数量过多,编译时出错,提示:
Conversion to Dalvik format failed:Unable to execute dex: method ID not in [0, 0xffff]: 65536
而问题产生的具体原因如下:
-
无法安装(Android 2.3 INSTALL_FAILED_DEXOPT)问题,是由dexopt的LinearAlloc限制引起的,在Android版本不同分别经历了4M/5M/8M/16M限制,目前主流4.2.x系统上可能都已到16M, 在Gingerbread或者以下系统LinearAllocHdr分配空间只有5M大小的, 高于Gingerbread的系统提升到了8M。Dalvik linearAlloc是一个固定大小的缓冲区。在应用的安装过程中,系统会运行一个名为dexopt的程序为该应用在当前机型中运行做准备。dexopt使用LinearAlloc来存储应用的方法信息。Android 2.2和2.3的缓冲区只有5MB,Android 4.x提高到了8MB或16MB。当方法数量过多导致超出缓冲区大小时,会造成dexopt崩溃。
-
超过最大方法数限制的问题,是由于DEX文件格式限制,一个DEX文件中method个数采用使用原生类型short来索引文件中的方法,也就是4个字节共计最多表达65536个method,field/class的个数也均有此限制。对于DEX文件,则是将工程所需全部class文件合并且压缩到一个DEX文件期间,也就是Android打包的DEX过程中, 单个DEX文件可被引用的方法总数(自己开发的代码以及所引用的Android框架、类库的代码)被限制为65536;
The Dalvik virtual machine was designed specifically for the Android mobile platform. The target systems have little RAM, store data on slow internal flash memory, and generally have the performance characteristics of decade-old desktop systems. They also run Linux, which provides virtual memory, processes and threads, and UID-based security mechanisms.
Dalvik 虚拟机是专门为android 移动平台设计的,它的系统几乎没有内存,内部闪存存储数据非常慢,也没有桌面系统一般性能特征的那种表现。它是运行在LINUX平台上的,Linux为其提供虚拟内存,进程和线程,以及UID-based安全机制
The features and limitations caused us to focus on certain goals:
这种特点和限制让我们有下面的改进:
- Class data, notably bytecode, must be shared between multiple processes to minimize total system memory usage.
- 类数据,尤其是字节码,必须在多个进程之间共享,目的是减轻系统内存使用的总大小【加个前缀:经过opt处理】
- The overhead in launching a new app must be minimized to keep the device responsive.
- 启动一个新的app所用的开销必须最小,目的是保证设备可以响应。【翻译是这样理解,加个前缀是:经过opt这个过程可以让APP启动更快。实际上就是主dex不应该干很多事的】
- Storing class data in individual files results in a lot of redundancy, especially with respect to strings. To conserve disk space we need to factor this out.
- 把类数据存储