Android平台上的Java代码会被编译为字节码还是机器码?
Android平台Java代码编译产物说明
常规服务端/桌面端Java的编译链路确实是.java源码经javac编译为JVM可识别的标准Java字节码,存储在.class文件中,后续由JVM在运行时通过解释执行、JIT即时编译转换为对应平台机器码运行。但Android平台的编译运行逻辑和标准JVM场景有差异,代码产物并不是非字节码即机器码的二元关系,要分阶段看:
- 开发机构建打包阶段(产出APK/AAB安装包的阶段):Java源码首先会经过前置编译生成标准Java字节码,之后通过Android构建工具链(旧版本用
dx工具,新版本AGP默认用D8工具)将标准字节码转换为Android运行时(Android 5.0前为Dalvik,5.0及之后为ART)专属的Dalvik字节码,最终打包进安装包内的.dex文件。这个阶段默认不会直接生成面向移动设备硬件的原生机器码。 - 用户设备安装阶段:从Android 5.0将ART设为默认运行时开始,应用安装到设备时,系统会触发AOT(提前编译)流程,将dex文件中的Dalvik字节码一次性编译为适配当前设备CPU架构的原生机器码,存储在设备本地的oat文件中,后续应用运行可直接读取机器码执行,大幅降低运行时的解释开销。
- 应用运行阶段:ART并未完全移除JIT即时编译机制,对于AOT阶段未覆盖的高频执行热点代码,运行时会动态将这部分Dalvik字节码编译为机器码执行,同时会记录热点代码的配置文件,在设备空闲时触发增量AOT优化,进一步提升后续运行效率。
- 特殊构建优化场景:如果构建时开启了特定优化选项(比如配套基线Profile做安装包内预AOT、使用GraalVM Native Image做静态原生编译),也可以在打包阶段直接生成部分或全量指定CPU架构的机器码随安装包分发,但这属于可选优化能力,不是Android平台的默认编译行为。
注意:Android平台不存在默认将Java源码直接编译为机器码的构建链路,Dalvik字节码是Android安装包默认携带的标准代码分发格式,机器码要么是应用安装到用户设备后本地生成,要么是开启特殊优化后在构建阶段的额外产出。
内容的提问来源于stack exchange,提问作者Steven
相关产品推荐
相关产品推荐

