Android的编译过程 & Android dex 方法限制的一些总结

来源:互联网 发布:淘宝上的内衣有图评论 编辑:程序博客网 时间:2024/04/30 17:10

先来张图,抖索一下精神:



第一步:打包资源文件,生成R.java文件
【输入】Resource文件(就是工程中res中的文件)、Assets文件(相当于另外一种资源,这种资源Android系统并不像对res中的文件那样优化它)、AndroidManifest.xml文件(包名就是从这里读取的,因为生成R.java文件需要包名)、Android基础类库(Android.jar文件)
【输出】打包好的资源(一般在Android工程的bin目录可以看到一个叫resources.ap_的文件就是它了)、R.java文件(在gen目录中,大家应该很熟悉了)
【工具】aapt工具

第二步:处理AIDL文件,生成对应的.java文件(当然,有很多工程没有用到AIDL,那这个过程就可以省了)
【输入】源码文件、aidl文件、framework.aidl文件
【输出】对应的.java文件
【工具】aidl工具

第三步:编译Java文件,生成对应的.class文件
【输入】源码文件(包括R.java和AIDL生成的.java文件)、库文件(.jar文件)
【输出】.class文件
【工具】javac工具

第四步:把.class文件转化成Davik VM支持的.dex文件
【输入】 .class文件(包括Aidl生成.class文件,R生成的.class文件,源文件生成的.class文件),库文件(.jar文件)
【输出】.dex文件
【工具】javac工具

第五步:打包生成未签名的.apk文件
【输入】打包后的资源文件、打包后类文件(.dex文件)、libs文件(包括.so文件,当然很多工程都没有这样的文件,如果你不使用C/C++开发的话)
【输出】未签名的.apk文件
【工具】apkbuilder工具

第六步:对未签名.apk文件进行签名
【输入】未签名的.apk文件
【输出】签名的.apk文件
【工具】jarsigner

第七步:对签名后的.apk文件进行对齐处理(不进行对齐处理是不能发布到Google Market的)
【输入】签名后的.apk文件
【输出】对齐后的.apk文件
【工具】zipalign工具

补充: java compiler 到底做了什么事情:

 1.分析 java 源文件 2.搜索源文件路径 3.搜索类文件路径 4.加载依赖的类 5.把结果写入 .class 文件
其中 javac 主要的作用就是把 java 源文件编译为 class 文件。
class 文件中主要有三部分,一是 class 常量池,二是 java 类的各种属性结构,三是 method info 结构中的code[] 中保存的字节码指令序列,这三部分中,指令序列主要对应了 java 源文件中的方法中的语句;各种属性结构,主要对应了类中各种标识符的签名标签、属性修饰等,比如 字段、方法、接口、类 的各种修饰符,还有 method 签名的结构,比如 返回值、参数列表中的参数类型;常量池主要就是保存类的定义中涉及到的常量数据,比如 int long float double utf-8,其中所有涉及到的标识符、字符串最终就保存为 utf-8 形式。jvm 在执行这个 class 文件中的函数的时候,很重要的工作就是解析这些符号引用。

可参照:http://blog.csdn.net/zhaoyw2008/article/details/9264279

为什么会有这个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 官方博客就给出了这个方案。http://android-developers.blogspot.com/2011/07/custom-class-loading-in-dalvik.html
(在Android5.0之前,由于大部分使用的是Dalvik 运行时环境,Dalvik 运行时环境限制一个apk只能包含一个classes.dex文件。)

对于外部原因:
  使用配置脚本对第三方库中的方法进行清除;
使用ProGuard清除项目中无用的方法,不过效果不如上面的。主要思路:使用multidex support library让Android5.0之前的版本也能在一个apk里面包含多个.dex文件。具体使用方法请参看这篇文章:http://developer.android.com/tools/building/multidex.html
    Google不仅在工具上面做出了改进,还把自己的Google Play Service库也做了一番改动——从Google Play Service 6.5开始开始支持更细精度的依赖管理,也就是说你只需要Google Drive的api,而不需要google game,maps或者wallet等api的支持,那你就可以只引入Google Drive的api即可。这样可以在很大程度上减少Dex 方法限制出现的几率。

0 0
原创粉丝点击