使用 APK 分析器分析您的构建

Android Studio 包含一个 APK 分析器,可在构建过程完成后立即洞察 APK 或 Android 应用包的构成。使用 APK 分析器可以减少您在调试应用中 DEX 文件和资源问题上花费的时间,并有助于减小 APK 的大小。APK 分析器也可以通过命令行使用 apkanalyzer


使用 APK 分析器,您可以:

  • 查看应用中文件的绝对大小和相对大小,例如 DEX 文件和 Android 资源文件。
  • 了解 DEX 文件的构成。
  • 快速查看应用中文件的最终版本,例如 AndroidManifest.xml 文件。
  • 执行两个 APK 或应用包的并排比较。

项目打开时,有三种方法可以访问 APK 分析器:

  • 将 APK 或应用包拖到 Android Studio 的 **编辑器** 窗口中。
  • 切换到 **项目** 窗口中的 **项目** 视图,然后双击默认 build/output/apks/ 目录中的 APK。
  • 在菜单栏中选择 **构建 > 分析 APK**,然后选择您的 APK 或应用包。

查看文件和大小信息

APK 是遵循 ZIP 文件格式的文件。APK 分析器将每个文件或文件夹显示为一个实体,您可以展开该实体以导航到文件夹中。实体的层次结构反映了 APK 文件中文件和文件夹的结构。

APK 分析器显示每个实体的压缩文件大小(或“原始文件大小”)和下载文件大小值,如图 1 所示。**原始文件大小** 表示该实体对 APK 总大小的贡献。**下载大小** 表示该实体作为 Google Play 传输时的估计压缩大小。**总下载大小的百分比** 指示该实体占 APK 总下载大小的百分比。

图 1. APK 分析器中的文件大小。

查看 AndroidManifest.xml

如果您的项目包含多个 AndroidManifest.xml 文件(例如产品风格),或包含也提供清单文件的库,则这些文件将合并到应用中的单个文件中。此清单文件通常是 APK 或应用包中的二进制文件,但在 APK 分析器中选择时,将重建此实体的 XML 形式并显示。

此查看器可帮助您了解构建期间可能对应用进行的任何更改。例如,您可以了解您的应用程序依赖的库中的 AndroidManifest.xml 文件如何合并到最终的 AndroidManifest.xml 文件中。

此外,此查看器还提供一些 lint 功能。警告或错误将显示在右上角。图 2 显示了为所选清单文件报告的错误。

图 2. 所选清单文件的右上角显示错误图标。

查看 DEX 文件

APK 分析器的 DEX 文件查看器使您可以立即访问应用中 DEX 文件的底层信息。查看器提供类、包、总引用和声明计数,这有助于确定是否使用多 DEX 或如何删除依赖项以低于 64K DEX 限制

图 3 显示了一个中等大小的应用,该应用低于 64K DEX 限制。DEX 文件中的每个包、类和方法都在 **已定义方法** 和 **已引用方法** 列中列出了计数。

**已引用方法** 列计算 DEX 文件引用的所有方法。这通常包括在您的代码中定义的方法、依赖库以及代码使用的标准 Java 和 Android 包中定义的方法。这些是在每个 DEX 文件中计入 64K 方法限制的方法。

**已定义方法** 列仅计算在您的一个 DEX 文件中定义的方法,因此此数字是 **已引用方法** 的子集。

图 3. 中等大小的应用。

筛选 DEX 文件树视图

在 **类** 列表的正上方,APK 分析器提供用于查看所选 DEX 文件内容的筛选器,如图 4 所示。

图 4. 设置为显示 BuildConfig 的字段和方法的 DEX 筛选器。

要使用筛选器显示类中的所有方法和字段,请执行以下操作:

  1. 在 **文件** 列表中,选择 classes.dex 文件。
  2. 在 **类** 列表中,导航到并选择一个类。
  3. 展开您选择的类。
  4. 切换 **显示字段** 以显示或隐藏类字段。
  5. 切换 **显示方法** 以显示或隐藏类方法。
  6. 切换 **显示所有引用的方法或字段** 以显示或隐藏引用的包、类、方法和字段。

    在树视图中,斜体节点是未在所选 DEX 文件中定义的引用。DEX 文件可以引用在其他文件中定义的方法和字段。例如 System.out.println() 是对 Android 框架中 println() 方法的引用。

加载 ProGuard 映射

筛选器图标旁边是 ProGuard 映射图标。在您加载一组 ProGuard 映射文件(这些文件会添加 DEX 查看器的功能,例如反混淆名称(mapping.txt)、显示已删除的节点(usage.txt)以及指示无法删除的节点(seeds.txt))之前,ProGuard 图标为灰色。

您导入的 ProGuard 映射文件必须来自启用代码缩减后生成 DEX 文件的同一构建。

图 5. 加载 Proguard 映射…

要加载 ProGuard 映射文件,请执行以下操作:

  1. 单击 **加载 Proguard 映射…**。
  2. 导航到包含映射文件的项目文件夹,并加载所有文件、任何文件的组合或包含文件的文件夹。

    映射文件通常位于 project/app/build/outputs/mappings/release/。如果检测到此项目结构,则文件选择器默认为 **release** 文件夹。

    首先,文件选择器检查与 mapping.txtseeds.txtusage.txt 完全匹配的文件名。接下来,文件选择器检查文件名中是否包含文本 mappingusageseeds,并且以 .txt 结尾。例如 release-seeds-1.10.15.txt 就是一个匹配项。

以下列表描述了映射文件:

  • seeds.txt:ProGuard 配置阻止在缩减过程中删除的节点将以粗体显示。
  • mapping.txt:启用 **反混淆名称** ,以便您可以恢复 R8 混淆的节点的原始名称。例如,您可以将混淆的节点名称(如 abc)恢复为 MyClassMainActivitymyMethod()
  • usage.txt:启用 **显示已删除节点** ,以便您可以显示在缩减过程中 R8 删除的类、方法和字段。已恢复的节点将以删除线显示。

    有关使用 R8 混淆和最小化代码的更多信息,请参阅 缩减、混淆和优化您的应用

显示字节码、查找用法和生成 Keep 规则

**类** 列表视图中的节点具有以下选项的上下文菜单,可让您查看字节码、查找用法并显示一个对话框,其中显示要复制和粘贴到所选节点的 ProGuard 规则。右键单击 **类** 列表视图中的任何节点以显示其上下文菜单。

**显示字节码**:反编译所选类、方法或字段,并在对话框中显示 smali 字节码表示形式,如下所示:

图 6. init 方法的 DEX 字节码。

**查找用法**:显示 DEX 代码的哪些其他部分引用了所选类或方法,如图 7 所示。如果您已加载 seeds.txt,则以粗体显示的节点表示 ProGuard 配置阻止在缩减过程中删除它们。

图 7.MyClass 的引用。

**生成 Proguard Keep 规则**:显示您可以复制并粘贴到项目的 ProGuard 配置文件的 ProGuard 规则,如图 8 所示。这将防止在代码缩减阶段删除给定的包、类、方法或字段。有关更多信息,请参阅 自定义要保留的代码

图 8. 可以从对话框复制到 ProGuard 配置文件的 ProGuard 规则。

查看代码和资源实体

各种构建任务都会更改应用中的最终实体。例如,ProGuard 缩减规则可以更改最终代码,并且图像资源可以被 产品风格 中的资源覆盖。

要使用 APK 分析器查看文件的最终版本,请点击实体以预览文本或图像实体,如图 9 所示。

图 9. 最终图像资源的预览。

APK 分析器还可以显示各种文本和二进制文件。例如,resources.arsc 实体查看器允许您查看特定于配置的值,例如字符串资源的语言翻译。在图 10 中,您可以看到每个字符串资源的翻译。

图 10. 已翻译字符串资源的预览。

比较文件

APK 分析器可以比较两个不同的 APK 或应用包文件中实体的大小。当您需要了解您的应用与之前的版本相比为何增大时,这非常有用。

发布更新的应用之前,请执行以下操作

  1. 将您即将发布的应用版本加载到 APK 分析器中。
  2. 在 APK 分析器的右上角,点击与之前的 APK 比较...
  3. 在选择对话框中,找到上次发布给用户的构件,然后点击确定

    将出现一个类似于图 11 中所示的对话框,以帮助您评估更新可能对用户产生的影响。

图 11 显示了特定应用的调试版本和发布版本之间的差异。这些构建类型之间使用了不同的构建选项,这些选项会以不同的方式更改底层实体。

图 11. 调试版和发布版 APK 之间的差异。