使用 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. DEX 过滤器设置为显示 BuildConfig 的字段和方法。

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

  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 之间的差异。