我想使用命令行在我的设备(Nexus One - 而不是模拟器)上调试我的Android应用程序。
我对如何使用jdb和android.os.Debug.waitForDebugger
设置断点感到困惑。
假设我将以下代码放在我的主要活动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
即可立即继续运行应用程序而不会停止。
e.g。
jdb -attach localhost:8700
是否有办法在运行jdb
之前预设断点或启动jdb
设置断点然后附加?
答案 0 :(得分:3)
jdb在Linux中有一个配置文件:〜/ .jdrbc。例如,我在我的:
stop in net.richardriley.myproj.myact.onCreate
在设备模拟器开发设置中,您可以为相关的应用程序类设置“等待调试器”。运行应用程序,启动调试器,它将中断。
答案 1 :(得分:1)
不幸的是,VM无法告诉调试器它已经被挂起。如果初始状态不是“运行”,那么我试过的各种调试器会感到困惑。因此,在调试器连接后,VM必须恢复所有线程。 (唯一的例外是如果VM刚刚启动,在这种情况下,它可以发送一个特殊的“我刚开始”消息,指示它是否会运行或保持暂停。这在这里没有帮助。)< / p>
waitForDebugger()所做的是等到调试器的初始活动突发静止。在调试器连接之后,该方法将休眠,直到调试器没有活动1.5秒。这允许调试器在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)给自己一点时间来抨击断点。
答案 2 :(得分:0)
我尝试过两种解决方案(来自fadden和Richard Riley的解决方案),但没有一种解决方案。一旦jdb连接到调试端口(8700通过Dalvik),模拟器中启动的应用就会被解锁,但它会自行运行,而根本不与jdb同步。引入等待循环不会改变事物,并且.jdbrc中的断点命令不起作用。 jdb的答案总是“延迟断点等等。它将在加载类后设置。”,因为应用程序没有运行;但是,如果你输入“run”,答案是“没有暂停。”,因为应用程序已经在运行......