android java 调试工具_调试应用  |  Android 开发者  |  Android Developers

Auto

如果您希望 Android Studio 自动为您要调试的代码选择最合适的选项,请选择此调试类型。例如,如果您的项目包含任何 C 或 C++ 代码,Android Studio 会自动使用 Dual 调试类型。否则,Android Studio 会使用 Java 调试类型。

Java

如果您只想调试使用 Java 或 Kotlin 编写的代码,请选择此调试类型。Java 调试程序会忽略您在原生代码中设置的任何断点或观察点。

Native(仅适用于 C/C++ 代码)

如果您只想使用 LLDB 调试代码,请选择此调试类型。使用此调试类型时,Java 调试程序会话视图不可用。默认情况下,LLDB 只检查原生代码,而会忽略 Java 代码中的断点。如果您还想调试 Java 代码,应切换到 Auto 或 Dual 调试类型。

原生调试仅适用于满足以下要求的设备:

设备支持 run-as。

如需检查设备是否支持 run-as,请在连接到设备的 ADB shell 上运行以下命令:

run-as your-package-name pwd

将 your-package-name 替换为您应用的软件包名称。如果设备支持 run-as,该命令应返回,不会出现任何错误。

设备启用了 ptrace。

如需检查是否启用了 ptrace,请在连接到设备的 ADB shell 上运行以下命令:

sysctl kernel.yama.ptrace_scope

如果启用了 ptrace,该命令会输出值 0 或出现 unknown key 错误。如果未启用 ptrace,该命令会输出 0 以外的值。

Dual(仅适用于 C/C++ 代码)

如果您想在同时调试 Java 代码和原生代码与不同时调试这两种代码之间切换,请选择此调试类型。Android Studio 会将 Java 调试程序和 LLDB 都连接到您的应用进程,一个用于 Java 调试程序,一个用于 LLDB。这样一来,您不必重启应用或更改调试配置,便可同时对 Java 代码和原生代码中的断点进行检查。

在图 2 中,请注意 Debug 窗口标题右侧的两个标签页。由于应用同时包含 Java 代码和 C++ 代码,因此一个标签页用于调试原生代码,另一个用于调试 Java 代码(由 -java 指示)。

b85f79f76ffc6d1bfc28458b2a2024c1.png

图 2. 用于调试原生代码的标签页和用于调试 Java 代码的标签页

注意:如果您调试的是由编译器优化的原生代码,可能会收到以下警告消息:This function was

compiled with optimizations enabled. Some debugger features may not be

available。使用优化标记(如 -O 标记)时,编译器会对编译的代码进行更改,以使其更高效地运行。这可能会导致调试程序报告意外或不正确的信息,因为调试程序很难将优化的编译代码映射回原始源代码。因此,您应该在调试原生代码时停用编译器优化。

使用系统日志

系统日志会在您调试应用时显示系统消息。这些消息包括运行在设备上的应用产生的信息。如果您要使用系统日志调试应用,请确保您的代码在应用处于开发阶段时写入日志消息并输出有关异常的堆栈轨迹。

在代码中写入日志消息

如需在代码中写入日志消息,请使用 写入和查看日志。

以下示例展示了如何添加日志消息,以确定您的 Activity 启动时先前的状态信息是否可用:

Kotlin

import android.util.Log

...

private val TAG: String = MyActivity::class.java.simpleName

...

class MyActivity : Activity() {

...

override fun onCreate(savedInstanceState: Bundle?) {

...

if (savedInstanceState != null) {

Log.d(TAG, "onCreate() Restoring previous state")

/* restore state */

} else {

Log.d(TAG, "onCreate() No saved state available")

/* initialize app */

}

}

}Java

import android.util.Log;

...

public class MyActivity extends Activity {

private static final String TAG = MyActivity.class.getSimpleName();

...

@Override

public void onCreate(Bundle savedInstanceState) {

...

if (savedInstanceState != null) {

Log.d(TAG, "onCreate() Restoring previous state");

/* restore state */

} else {

Log.d(TAG, "onCreate() No saved state available");

/* initialize app */

}

}

}

在开发期间,您的代码还可以捕获异常并将堆栈轨迹写入系统日志:

Kotlin

fun someOtherMethod() {

try {

...

} catch (e : SomeException) {

Log.d(TAG, "someOtherMethod()", e)

}

}Java

void someOtherMethod() {

try {

...

} catch (SomeException e) {

Log.d(TAG, "someOtherMethod()", e);

}

}

注意:当您准备好发布应用时,应从代码中移除调试日志消息和堆栈轨迹输出调用。为此,您可以设置一个 DEBUG 标记,并将调试日志消息放入条件语句。

查看系统日志

您可以在 Logcat 窗口中查看和过滤调试消息及其他系统消息。例如,您可以看到发生垃圾回收时显示的消息,或您使用 Log 类添加到应用的消息。

如需使用 logcat,请开始调试并选择底部工具栏中的 Logcat 标签页,如图 3 所示。

6c0ce38ea501d5a4b45867be74f20cc5.png

图 3. 包含过滤器设置的“Logcat”窗口

有关 Logcat 及其过滤选项的说明,请参阅使用 Logcat 写入和查看日志。

使用断点

Android Studio 支持几种类型的断点,这些断点可触发不同的调试操作。最常见的类型是行断点,用于在指定的代码行暂停应用的执行。暂停时,您可以检查变量,对表达式求值,然后继续逐行执行,以确定运行时错误的原因。

如需添加行断点,请按以下步骤操作:

找到您要暂停执行的代码行,然后点击该代码行的左侧边线,或将文字插入点置于该行上并按 Ctrl+F8(在 Mac 上,按 Command+F8)。

如果您的应用已在运行,您不必更新应用便可添加断点 - 只需点击 Attach debugger to Android proccess 图标

198933a4d58bd36384dbb3fb2bca3f76.png。否则,请点击 Debug 图标

ad0cd886ed6ff20ca0ce1d592a00e718.png 开始调试。

a888e2ece0096e3d965f48bc28fda68c.png

图 3. 当您设置断点时,相应的代码行旁边会出现一个红点

当您的代码执行到达该断点时,Android Studio 会暂停应用的执行。您随后可以使用 Debugger 标签页中的工具确定应用的状态:

如需检查变量的对象树,请在 Variables 视图中将其展开。如果 Variables 视图不可见,请点击 Restore Variables View 图标

a913cb968f47f8d983cec2b19ff5f2a3.png

如需在当前执行点对表达式求值,请点击 Evaluate Expression 图标

e8e32124328234b85d840321b3699828.png

如需前进到代码中的下一行(而不进入方法),请点击 Step Over 图标

53275c117cb446f60f3c4ca77ae54df6.png

如需前进到方法调用内的第一行,请点击 Step Into 图标

374d3372d941da2789fde28cfaeb8e51.png

如需前进到当前方法之外的下一行,请点击 Step Out 图标

6f83f8d606ce2b517bfb73903f8ce407.png

如需继续正常运行应用,请点击 Resume Program 图标

9f3121e501e5d99d509724904db1fe3a.png

如果您的项目使用了任何原生代码,默认情况下,Auto 调试类型会将 Java 调试程序和 LLDB 作为两个单独的进程都连接到您的应用。这样一来,您无需重启应用或更改设置,便可在检查 Java 断点与 C/C++ 断点之间进行切换。

注意:要使 Android Studio 检测到 C 或 C++ 代码中的断点,您需要使用支持 LLDB 的调试类型,如 Auto、Native 或 Dual。您可以通过修改调试配置,更改 Android Studio 使用的调试类型。如需详细了解不同的调试类型,请阅读有关使用其他调试类型的部分。

当 Android Studio 将应用部署到目标设备时,系统会打开“Debug”窗口,在该窗口中为每个调试程序进程显示一个标签页或调试会话视图,如图 4 所示。

aa7ec029056b83c6446fddf14b6e69e9.png

图 4. 使用 LLDB 调试原生代码

当 LLDB 调试程序遇到 C/C++ 代码中的断点时,Android Studio 会切换到 标签页。还会显示 Frames、Variables 和 Watches 窗格,其作用与您调试 Java 代码时完全相同。虽然 LLDB 会话视图中未显示 Threads 窗格,但您可以使用 Frames 窗格中的下拉列表访问您的应用进程。您可以在有关如何调试窗口帧和检查变量的部分中详细了解这些窗格。

注意:检查原生代码中的断点时,Android 系统会挂起运行应用的 Java 字节码的虚拟机。这意味着,检查原生代码中的断点时,您无法与 Java 调试程序进行交互,或从 Java 调试程序会话检索任何状态信息。

当 Java 调试程序遇到 Java 代码中的断点时,Android Studio 会切换到 -java 标签页。

使用 LLDB 进行调试时,您可以利用 LLDB 会话视图中的 LLDB 终端向 LLDB 传递命令行选项。如果您想让 LLDB 在您每次开始调试应用时都执行某些命令(在调试程序连接到您的应用进程之前或之后执行),您可以将这些命令添加到您的调试配置中。

调试 C/C++ 代码时,您还可以设置特殊类型的断点,这类断点称为“观察点”,可以在您的应用与特定内存块进行交互时挂起您的应用进程。如需了解详情,请阅读有关如何添加观察点的部分。

查看和配置断点

如需查看所有断点并配置断点设置,请点击 Debug 窗口左侧的 View Breakpoints 图标

983ca42b37a47c1c9bf2c841c6edb833.png。此时将显示 Breakpoints 窗口,如图 5 所示。

0d5eeb72daccaebf4233a5bac6b0376a.png

图 5.“Breakpoints”窗口列出了当前的所有断点,并包括每个断点的行为设置

您可以从 Breakpoints 窗口左侧的列表中启用或停用每个断点。如果停用了某个断点,Android Studio 不会在应用遇到该断点时将其暂停。从列表中选择某个断点即可配置其设置。您可以将某个断点配置为最初处于停用状态,让系统在遇到其他断点后将其启用。您还可以配置在遇到某个断点后是否应将其停用。如需为任何异常设置断点,请在断点列表中选择 Exception Breakpoints。

调试窗口帧

在 Debugger 窗口的 Frames 窗格中,您可以检查导致遇到当前断点的堆栈帧。这样,您就可以浏览和检查堆栈帧,同时还可以检查 Android 应用中的线程列表。如需选择线程,请使用线程选择器下拉列表并查看其堆栈帧。点击帧中的元素会在编辑器中打开源代码。您还可以按窗口帧指南中的说明自定义线程呈现和导出堆栈帧。

检查变量

系统将您的应用停止在某个断点处并且您从 Frames 窗格中选择某个帧后,您可以在 Debugger 窗口的 Variables 窗格中检查变量。此外,您还可以在 Variables 窗格中使用选定帧内提供的静态方法和/或变量对临时表达式求值。

Watches 窗格提供的功能类似,不同的是添加到 Watches 窗格的表达式可跨调试会话存留。您应该为自己经常访问或者提供的状态对当前调试会话有帮助的变量和字段添加观察点。Variables 和 Watches 窗格如图 6 所示。

如需向 Watches 列表中添加变量或表达式,请按以下步骤操作:

开始调试。

在 Watches 窗格中,点击 Add 图标

e60f378778186c3b5dda2a8715c6f9ec.png

在随后显示的文本框中,输入您要观察的变量或表达式的名称,然后按 Enter 键。

如需从 Watches 列表中移除某一项,请选择该项,然后点击 Remove 图标

811c2f98b2dbc303f98df44680ffc4dc.png

选择某一项,然后点击 Up 图标

f3a77d893883dbe3f11d3f11ae9860d2.png 或 Down 图标

93b46ed83d59589ccf05100c3a7aa0f3.png,可对 Watches 列表中的元素重新排序。

0050d36b45bd35d3d5500b8ff8495b9a.png

图 6.“Debugger”窗口中的“Variables”和“Watches”窗格

添加观察点

调试 C/C++ 代码时,您可以设置特殊类型的断点,这类断点称为“观察点”,可以在您的应用与特定内存块进行交互时挂起您的应用进程。例如,如果您为某个内存块设置了两个指针并为其分配了一个观察点,则使用任一指针访问该内存块都会触发该观察点。

在 Android Studio 中,您可以通过选择特定变量在运行时创建观察点,但 LLDB 只会将该观察点分配给系统分配给该变量的内存块,而不会分配给变量本身。这与将变量添加到 Watches 窗格不同,将变量添加到该窗格后,您可以观察变量的值,但当系统读取或更改内存中的变量值时,不允许您挂起应用进程。

注意:当您的应用进程退出某个函数,并且系统从内存中解除分配其局部变量时,您需要重新分配为这些变量创建的所有观察点。

如需设置观察点,您必须满足以下要求:

您的目标物理设备或模拟器使用 x86 或 x86_64 CPU。如果您的设备使用 ARM CPU,则您必须将变量的内存地址边界分别按照 4 字节(对于 32 位处理器)或 8 字节(对于 64 位处理器)对齐。您可以通过在变量声明中指定 __attribute__((aligned(num_bytes))),在原生代码中对齐变量,如下所示:

// For a 64-bit ARM processor

int my_counter __attribute__((aligned(8)));

您已经分配了不超过三个观察点。Android Studio 在 x86 或 x86_64 目标设备上最多只支持四个观察点。其他设备支持的观察点数量可能更少。

注意:使用 32 位 ARM ABI 调试应用时,添加观察点或将鼠标悬停在代码内的变量上以检查其值可能会导致崩溃。为了解决此问题,请使用 64 位 ARM、x86 或 x86_64 二进制文件进行调试。此问题将在即将推出的 Android Studio 版本中得到解决。

如果您满足上述要求,便可以添加观察点,具体操作步骤如下:

在应用在某个断点处挂起的情况下,转到 LLDB 会话视图中的 Variables 窗格。

右键点击占用您要跟踪的内存块的变量,然后选择 Add Watchpoint。此时将显示一个用来配置观察点的对话框,如图 7 所示。

e1c2da404004cdff60eead19199b2173.png

图 7. 向内存中的变量添加观察点

使用以下选项配置观察点:

Enabled:如果您要告知 Android Studio 暂时忽略相应的观察点,可以取消选择此选项。Android Studio 仍会保存您的观察点,以便您稍后在调试会话中访问。

Suspend:默认情况下,Android 系统会在其访问您分配给观察点的内存块时挂起应用进程。如果您不希望出现此行为,可以取消选择此选项。这样会显示一些附加选项,即 Log message to console 和 Remove [the watchpoint] when hit,您可以使用这些选项自定义系统与观察点进行交互时的行为。

Access Type:选择当您的应用尝试对系统分配给变量的内存块执行 Read 或 Write 操作时是否应触发您的观察点。如需在执行读取或写入操作时触发您的观察点,请选择 Any。

点击 Done。

如需查看所有观察点并配置观察点设置,请点击 Debug 窗口左侧的 View Breakpoints 图标

983ca42b37a47c1c9bf2c841c6edb833.png。此时将显示 Breakpoints 对话框,如图 8 所示。

628f275eee0c49e25a52bb400abd731f.png

图 8.“Breakpoints”对话框列出了当前的观察点,并包括每个观察点的行为设置

添加观察点后,点击 Debug 窗口左侧的 Resume Program 图标

9f3121e501e5d99d509724904db1fe3a.png 可继续执行应用进程。默认情况下,如果您的应用尝试访问您设置了观察点的内存块,Android 系统会挂起您的应用进程,您的应用最后执行的那行代码旁边会出现一个观察点图标

f3831e45c99c7c5d8f01fbc9186c171c.png,如图 9 所示。

ba176ae3ac2c738fc88f63ff9e1193dc.png

图 9. Android Studio 会指示您的应用在即将触发观察点之前执行的那行代码

查看和更改资源值显示格式

在调试模式下,您可以查看 Java 代码中的变量的资源值并为其选择其他显示格式。在显示了 Variables 标签页并选择了帧的情况下,执行以下操作:

在 Variables 列表中,右键点击资源行的任意位置以显示下拉列表。

在下拉列表中选择 View as,然后选择您要使用的格式。

可供选择的格式取决于选定资源的数据类型。您可能会看到以下一个或多个选项:

Class:显示类定义。

toString:显示字符串格式。

Object:显示对象(类实例)定义。

Array:以数组格式显示。

Timestamp:按 yyyy-mm-dd hh:mm:ss 格式显示日期和时间。

Auto:Android Studio 根据数据类型选择最合适的格式。

Binary:显示使用 0 和 1 表示的二进制值。

MeasureSpec:从父级传递给选定子级的值。请参阅 MeasureSpec。

Hex:显示为十六进制值。

Primitive:显示为使用原始数据类型表示的数值。

Integer:显示 Integer 类型的数值。

您可以按以下步骤创建自定义格式(数据类型渲染程序):

右键点击资源值。

选择 View as。

选择 Create。此时将显示 Java Data Type Renderers 对话框。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值