Android Dev Summit, October 23-24: two days of technical content, directly from the Android team. Sign-up for livestream updates.

分析和调试预编译 APK

使用 Android Studio 3.0 及更高版本,您可以分析和调试 APK,而不必从 Android Studio 项目编译这些 APK。不过,您需要确保是在启用了调试功能的情况下使用 APK。

要开始调试 APK,请在 Android Studio 的 Welcome 屏幕中点击 Profile or debug APK。或者,如果您已经打开一个项目,请在菜单栏中依次点击 File > Profile or Debug APK。在下一个对话框窗口中,选择要导入 Android Studio 的 APK,然后点击 OK

Android Studio 随后会显示未封装的 APK 文件,类似于图 1。这不是完全反编译的文件集,不过它为 .dex 文件提供了我们更容易读懂的 .smali 版本。

图 1. 将预编译 APK 导入 Android Studio。

在 Project 窗格的 Android 视图中,您可以检查 APK 的以下内容:

  • APK file:双击 APK 可以打开 APK 分析器。
  • manifests:包含从 APK 中提取的应用清单。
  • java:包含 Android Studio 根据 APK 的 DEX 文件反汇编(成为 .smali 文件)的 Java 代码。此目录中的每个 .smali 文件对应于一个 Java 类。
  • cpp:如果应用包含原生代码,此目录将包含 APK 的原生库(.so 文件)。
  • External Libraries:包含 Android SDK。

您可以立即使用 Android Profiler 开始测试应用的性能。

要调试应用的 Java 代码,您需要附加 Java 源代码并在 .java 文件中添加断点。同样,要调试原生代码,您必须附加原生调试符号

附加 Java 源代码

默认情况下,Android Studio 会从您的 APK 中提取 Java 代码并将其另存为 .smali 文件。要使用断点调试 Java 代码,您需要将 Android Studio 指向与要调试的 .smali 文件对应的 .java 源文件。

要附加 Java 源代码,请按以下步骤操作:

  1. Project 窗格(使用 Android 视图)中双击 .smali 文件。打开该文件后,编辑器会显示一个要求您选择 Java 源代码的警告横幅,类似于图 1 中所示。
  2. 点击编辑器窗口顶部横幅中的 Attach Java Sources
  3. 转到包含应用的 Java 源文件的目录,然后点击 Open

Project 窗口中,Android Studio 会将 .smali 文件替换为对应的 .java 文件。此外,Android Studio 还会自动包含内部类。现在,您可以添加断点并像往常一样调试您的应用

附加原生调试符号

如果您的 APK 包含的原生库(.so 文件)不包含调试符号,Android Studio 会在 Messages 窗口中向您显示一条警告,类似于图 1 中所示。如果不附加可调试的原生库,您将无法调试 APK 的原生代码或使用断点。

如果您通过版本号编译 APK 中的原生库,Android Studio 会检查符号文件中的版本号是否与原生库中的版本号匹配,如果不匹配,会拒绝符号文件。如果您不是使用版本号编译的原生库,则提供不正确的符号文件可能会导致调试出现问题。

要附加可调试的原生库,请按以下步骤操作:

  1. 如果您还未下载,请务必下载 NDK 和工具
  2. Project 窗口中的 cpp 目录(只有在您选择了 Android 视图时才可见,如图 2 所示)下,双击一个不包含调试符号的原生库文件。编辑器将显示一个表格,其中列出了您的 APK 支持的所有 ABI。
  3. 点击编辑器窗口右上角的 Add
  4. 转到包含要附加的可调试原生库的目录,然后点击 OK

如果 APK 和可调试原生库是使用不同的工作站编译的,您还需要指定本地调试符号的路径,具体操作步骤如下:

  1. 在编辑器窗口的 Path Mappings 部分中的 Local Paths 列下修改相关字段,添加缺失调试符号的本地路径,如图 2 所示。在大多数情况下,您只需提供根文件夹的路径,Android Studio 会自动检查子目录以映射其他源路径。Android Studio 还会自动将远程 NDK 的路径映射到您的本地 NDK 下载路径。
  2. 点击编辑器窗口的 Path Mappings 部分中的 Apply Changes

图 2. 提供本地调试符号的路径。

现在,您应该会在 Project 窗口中看到原生源文件。您可以打开这些原生文件以添加断点并像往常一样调试您的应用。您还可以通过点击编辑器窗口的 Path Mappings 部分中的 Clear 来移除映射。

已知问题:将调试符号附加到 APK 时,APK 和可调试的 .so 文件必须使用相同的工作站或编译服务器进行编译。