我想使用命令行在我的设备(Nexus One - 而不是模拟器)上调试我的 Android 应用程序。
我对如何使用 jdb 和 android.os.Debug.waitForDebugger
设置断点感到困惑。
假设我将以下代码放在我的主要 Activity onCreate
中:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
android.os.Debug.waitForDebugger();
int j = 10;
int r = j;
}
使用
ddms
我可以看到我的应用程序在我启动它时正在等待调试器(红色错误图标)。但是,我不明白如何在
waitForDebugger()
调用之后设置断点,以便我可以开始单步执行。显然,只附加
jdb
将立即继续运行应用程序而不会停止。例如
jdb -attach localhost:8700
有没有办法在运行
jdb
之前预设断点或启动 jdb
设置断点然后附加的方法? 最佳答案
不幸的是,VM 无法告诉调试器它已经挂起。如果初始状态不是“正在运行”,我尝试过的各种调试器都会感到困惑。因此,在调试器连接后,VM 必须恢复所有线程。 (上述唯一的异常(exception)是如果 VM 刚刚启动,在这种情况下,它可以发送一个特殊的“我刚刚启动”消息,指示它是要运行还是保持挂起。这在这里没有帮助。)
waitForDebugger() 所做的是等到调试器的初始 Activity 爆发安静下来。调试器连接后,该方法将休眠,直到调试器在 1.5 秒内没有任何 Activity 。这允许调试器有机会在 VM 恢复之前设置任何断点。
对于 Eclipse,这个 hack 效果很好,因为您可以在附加之前配置断点。对于 jdb,我无法在它启动后告诉它附加,因此您必须快速敲击键盘或使用某种配置文件(我也没有看到)。
你可以用不同的方式解决这个问题:在 waitForDebugger 调用下面,添加一个循环,如:
static volatile boolean staticField = false;
...
while (!MyClass.staticField) {
Log.d(tag, "waiting for go");
Thread.sleep(2000);
}
然后,在你按照你想要的方式配置了 jdb 之后,使用类似的东西:
> set MyClass.staticField = true
如果你很快,你可以跳过循环,只使用 Thread.sleep(5000) 给自己一点额外的时间来猛击断点。
关于Android 与 jdb 混淆使用 waitForDebugger,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3107587/