使用 APK 分析器分析您的 build

Android Studio 包含 APK 分析器,可在构建流程完成后立即深入了解您的 APK 或 Android App Bundle 的构成。使用 APK 分析器可以减少调试应用中的 DEX 文件和资源问题所花费的时间,并有助于缩小 APK 大小。APK 分析器也可通过命令行使用 apkanalyzer 工具。


使用 APK 分析器,您可以:

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

打开项目时,可通过三种方式访问 APK 分析器:

  • 将 APK 或应用 bundle 拖动到 Android Studio 的 Editor 窗口中。
  • 切换到 Project 窗口中的 Project 视图,然后双击默认 build/output/apks/ 目录中的 APK。
  • 在菜单栏中选择 Build > Analyze APK,然后选择您的 APK 或应用 bundle。

查看文件和大小信息

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

APK 分析器会显示每个实体的压缩文件大小(或“原始文件大小”)和下载文件大小值,如图 1 所示。原始文件大小表示实体对总 APK 大小的贡献。下载大小表示实体在 Google Play 分发时的预估压缩大小。占总下载大小的百分比表示实体占 APK 总下载大小的百分比。

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

查看 AndroidManifest.xml

如果您的项目包含多个 AndroidManifest.xml 文件(例如用于产品变种)或包含提供清单文件的库,它们会合并到应用中的单个文件。此清单文件通常是 APK 或应用 bundle 中的二进制文件,但在 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. DEX 过滤器设置为显示 BuildConfig 的字段和方法。

要使用过滤器显示类内的所有方法和字段,请按以下步骤操作:

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

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

加载 ProGuard 映射文件

过滤图标旁边是 ProGuard 映射图标。ProGuard 图标会灰显,直到您加载一组 ProGuard 映射文件,这些文件会为 DEX 查看器添加功能,例如去混淆名称 (mapping.txt)、显示已移除的节点 (usage.txt) 以及指示无法移除的节点 (seeds.txt)。

您导入的 ProGuard 映射文件必须来自生成已启用代码缩减功能的 DEX 文件的同一 build。

图 5. 加载 Proguard 映射文件...

要加载 ProGuard 映射文件,请按以下步骤操作:

  1. 点击 Load Proguard mappings...
  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 规则。右键点击 Class 列表视图中的任何节点即可显示其上下文菜单。

显示字节码:反编译选定的类、方法或字段,并在对话框中显示 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 或应用 bundle 文件中实体的大小。这有助于您了解与之前版本相比,您的应用为何大小增加。

在发布更新的应用之前,请按以下步骤操作:

  1. 将您即将发布的版本加载到 APK 分析器中。
  2. 在 APK 分析器的右上角,点击 Compare with previous APK...
  3. 在选择对话框中,找到上次发布给用户的 artifact,然后点击 OK

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

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

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