使用 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 文件中的基础信息。查看器提供类、包、总引用和声明计数,这可以帮助您决定是否使用 multidex 或如何删除依赖项以降低到 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 和发布 APK 之间的差异。