返回「计算机、信息技术与工程」

Android应用程序与运行环境

Android应用程序与运行环境 JVM(Java Virtual Machine)、Dalvik 和 ART(Android Runtime)从广义上来说,都可以归类为 "Java 运行时环境" (Java Runtime Environment)的一部分,核心目标是执行 Java 字节码或类似 Java 的程序。

更多
Markdown 结构化数据
本文目录 13 个章节

Android应用程序与运行环境

JVM(Java Virtual Machine)、Dalvik 和 ART(Android Runtime)从广义上来说,都可以归类为 "Java 运行时环境"(Java Runtime Environment)的一部分,核心目标是执行 Java 字节码或类似 Java 的程序。

Dalvik 和 ART可以看作是针对 Android 平台优化的 Java 虚拟机变种,旨在支持 Java 生态和语言特性,负责解释、编译和运行 Java 或 Kotlin 代码(在 Android 中)。

JVM(Java Virtual Machine)

JVM 是一种运行 Java 字节码(.class 文件)的虚拟机,作为 Java 平台的核心组件。它提供了一种跨平台的运行环境,使 Java 程序能够在多种操作系统上运行。

工作原理

  1. Java 字节码:Java 源代码(.java 文件)通过编译器 javac 转换为 .class 文件(Java 字节码)。
  2. 加载与解释:JVM 通过类加载器(ClassLoader)加载 .class 文件,并将其转换为虚拟机可以执行的指令。
  3. 执行方式
    • 解释执行:逐行解释 .class 文件中的字节码并执行。
    • JIT(Just-In-Time)编译:将热点代码(频繁执行的代码)编译为本地机器码,提高性能。

特点

  • 跨平台性:Java 程序可以在任何安装了 JVM 的系统上运行。
  • 面向通用场景:JVM 的设计初衷是服务于多种环境和设备。

Dalvik

Dalvik 是 Android 早期的虚拟机,用于在移动设备上高效运行 Android 应用程序。它能够运行 Android 专用的 .dex 文件(Dalvik Executable)。

工作原理

  1. 字节码格式
    • Android 开发中的 .class 文件会被转换为 .dex 文件,这是一种经过优化的字节码格式。
  2. 基于寄存器的架构
    • 不同于 JVM 基于栈的指令集,Dalvik 使用寄存器作为操作数存储区。这种方式减少了指令数量,提高了执行效率。
  3. 解释执行
    • Dalvik 主要通过解释器逐行执行 .dex 字节码。

特点

  • 为移动设备优化
    • 低内存占用。
    • 更高效的指令集。
  • 单独进程模型
    • 每个 Android 应用都有自己的 Dalvik 实例,运行在独立的进程中。
  • GC(垃圾回收)优化
    • 针对低内存设备进行了垃圾回收算法优化。

ART(Android Runtime)

ART 是 Android 的现代运行时,作为 Dalvik 的替代者,从 Android 5.0(Lollipop)开始成为默认运行时。ART 的目标是进一步提高性能,优化资源使用。

工作原理

  1. AOT(Ahead-Of-Time)编译
    • 在应用安装时,ART 会将 .dex 文件编译为本地机器码(ELF 文件),这样在运行时无需解释或即时编译。
  2. JIT(Just-In-Time)编译
    • 从 Android 7.0 开始,ART 增加了 JIT 编译器,用于在运行时优化热点代码。
  3. 解释执行
    • ART 也支持解释执行未编译的代码。

特点

  • 高性能
    • AOT 编译减少了运行时的计算开销,启动速度更快。
  • 优化内存使用
    • ART 支持共享类和字符串池,减少了重复数据的内存占用。
  • 改进的垃圾回收
    • ART 提供了更高效的垃圾回收机制(如并行 GC 和增量 GC)。
  • 调试和分析支持
    • 支持更精细的调试功能,例如更好的堆栈跟踪和内存泄漏检测。

DEX( Dalvik Executable) 是 Android 平台的一种字节码格式。 A bytecode format designed specifically for Android that's optimized for a minimal memory footprint.

所有 Android 应用程序的代码最终都会以 DEX 文件的形式运行在 Android Runtime (ART) 或 Dalvik 虚拟机上。

特点

  • DEX 文件的设计目标是减少运行时的内存使用。
  • 指令集被精简并优化,以适应移动设备的有限资源。
  • 不同于 Java 的 .class 文件(每个类一个文件),一个 DEX 文件可以包含多个类的字节码。这种设计减少了文件数量和存储开销。
  • 虽然 DEX 文件是为 Android 优化的,但它仍然保持了平台无关性,类似于 JVM 的字节码。

构建

在构建 APK 的过程中,所有 JAR 文件中的 Java 字节码会被 d8dx 工具转换为 DEX 格式。

  • JAR 文件中包含的是标准的 Java 字节码(.class 文件)。
  • 在构建时,这些 .class 文件会被统一合并并转换为一个或多个 .dex 文件。
  • 最终生成的 DEX 文件会被打包到 APK 的 classes.dex 文件中。

Unity 在构建 Android 工程时,会将所有 JAR 插件统一传递给 Android 构建工具链(Gradle 或 UnityPlayerActivity 的构建脚本),最终处理方式取决于这些工具链: - 普通 JAR 文件:字节码会被转换为 DEX。 - 动态加载 JAR 文件:如果指定为动态加载,JAR 会保留原始形式。

加载和执行

  1. 加载 DEX 文件 DEX 文件通常通过虚拟机加载和解释。加载器主要包括:
  • ClassLoader:加载和解析 DEX 文件中的类。
  • DexClassLoader:支持在运行时动态加载外部的 DEX 文件。
  1. 解释与编译
  • 解释执行:ART 和 Dalvik 虚拟机可以直接解释 DEX 字节码。
  • 编译执行
    • 在 ART 中,常见方法会被 JIT 编译为本地机器码。
    • 在应用安装时,ART 会将 DEX 文件通过 AOT 编译为本地代码。

相关工具

  • d8
    • 新版的字节码转换工具,用于将 .class 转换为 .dex
    • dx 更高效,支持增量编译。
  • dexdump
    • 用于分析和查看 DEX 文件内容的工具。
  • proguard
    • 用于混淆代码,减小 DEX 文件的大小,并保护代码不被反编译。