Eclipse Android 调试器 - 我的代码在哪里导致异常?
Posted
技术标签:
【中文标题】Eclipse Android 调试器 - 我的代码在哪里导致异常?【英文标题】:Eclipse Android Debugger - Where in my code did I cause the exception? 【发布时间】:2011-06-21 00:33:18 【问题描述】:诚然,我的问题与这个问题基本相同,但似乎一直没有答案:
NullPointerException in handleStopActivity -- No reference to my code in stack trace
上周内下载了 Eclipse Helios、android 开发者工具插件和 JDK。我在我的设备上弄乱了一个应用程序,在调试模式下运行它,但它意外终止。我意识到我已经导致了 NullPointerException,而且问题本身并不会长期存在。
然而,问题在于调试器似乎无法识别在我的代码中引发异常的位置。堆栈跟踪没有引用我的代码。
确实,如果我将以下内容放入 OnCreate()
方法中,我会遇到同样的问题
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//lI("onCreate()"); //A silly logging thing I messed around with
Integer iDareYou = null;
iDareYou.byteValue();
值得称赞的是,Eclipse 确实警告我,代码可能会在我面前爆炸。但是当我在我的设备上实际运行它时,返回的堆栈跟踪如下:
Thread [<1> main] (Suspended (exception RuntimeException))
ActivityThread.performLaunchActivity(ActivityThread$ActivityRecord, Intent) line: 2787
ActivityThread.handleLaunchActivity(ActivityThread$ActivityRecord, Intent) line: 2803
ActivityThread.access$2300(ActivityThread, ActivityThread$ActivityRecord, Intent) line: 135
ActivityThread$H.handleMessage(Message) line: 2136
ActivityThread$H(Handler).dispatchMessage(Message) line: 99
Looper.loop() line: 144
ActivityThread.main(String[]) line: 4937
Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method]
Method.invoke(Object, Object...) line: 521
ZygoteInit$MethodAndArgsCaller.run() line: 868
ZygoteInit.main(String[]) line: 626
NativeStart.main(String[]) line: not available [native method]
我四处寻找一些答案,不幸的是,我只能提出“为什么我的 Android 应用程序会导致 NullPointerException”的问题?品种。
我希望找出我应该做的不同的事情,以便能够在我的代码中找到导致异常的点......因为我确信这种能力在某些时候会派上用场指向未来!
将对其进行编辑以添加一些信息。正如下面的第一条评论所提到的,调试器挂起线程的状态不是应用程序的“最终”状态。按几次“恢复”将进程移动到进程实际终止的位置,但遗憾的是,Eclipse/ADT 调试窗口中没有显示有用的堆栈跟踪。 然而,此时我粘贴在上面的堆栈跟踪 Followed By 我的代码中 NPE 堆栈跟踪的前 3 个唯一行输出到 LogCat。我以前曾查看过 LogCat 是否有任何我可以使用的东西,但很可能是在我在调试器中按下“恢复”以将进程移动到此状态之前。不幸的是,这样做永远不会在实际调试器中的代码中显示 NPE 的堆栈跟踪。
但消息并不全是坏消息 - 从右侧“变量”窗口中的信息中,我可以看到线程的当前范围内有一个 NPE,所以这至少会给我一个线索,即 NPE 是继续(当然还有 LogCat)。
因此,根据不同主题的建议,我发现的最佳解决方法是为 NullPointerException 添加一个“Caught and Uncaught”断点。当我这样做并重新启动时,调试器会在我的代码中显示 NPE 的堆栈跟踪,并将编辑窗口直接移动到我导致 NPE 的行。
目前我认为这是因为 NPE 被 Android 框架捕获(并且可能再次被抛出)。 看来最初的困境是由于 Eclipse/ADT/DalvikVM 调试堆栈跟踪窗口不包括堆栈跟踪中显示的“由”信息(据我所知)“稍后"出现在 LogCat 中。我将进一步调查这是否可以补救:)
我很欣赏 Bert F 的建议,因为我并不完全意识到该线程尚未处于“最终”状态。虽然堆栈跟踪确实 [稍后] 显示在 LogCat 中,但我没有在 LogCat 中“错过”它,因为它[尚未]在那里,我错过的是点击“恢复”,这会导致堆栈跟踪在 LogCat 中输出。
即使我最初使用断点让调试器停止在我的代码中的行,但有一种情况是,我可以在恢复线程后最终获得 LogCat 中的堆栈跟踪,这将有效地解决问题。我真正要求的唯一另一件事是让调试器停止在我的代码中导致异常的行,而不是被Android框架捕获并随后重新抛出。但我相信这将是一个不同的问题 :) 如果我单击 LogCat 窗口中显示的堆栈跟踪中的适当行,Eclipse 将把我发送到那里。
【问题讨论】:
看起来程序在调试器中暂停并且没有继续打印异常和完整的堆栈跟踪。让程序继续,然后显示完整的异常消息和完整的堆栈跟踪会很有用。通常一个 NPE 被多个异常包裹(在堆栈跟踪中打印“引起”) - 最低的“引起”消息可能是最重要的。此外,如果您知道您的 rev,它可能有助于找到与堆栈跟踪匹配的源。 伯特,如果您想重新发布作为答案,我愿意接受,可以说“推送简历将获得我要求的堆栈跟踪” 你不是唯一一个不明白这一点的人!不过你是对的——点击 play 几次让异常冒泡,然后查看 LogCat 而不是堆栈跟踪。我用过很多很多的 IDE,我觉得“我的代码哪一行出错”似乎是只有专家才能发现的东西,这似乎很奇怪...... 你试过 IntelliJ 吗?也许其中的调试器效果更好。 【参考方案1】:我运行了您的确切代码,LogCat 给了我以下例外:
Caused by: java.lang.NullPointerException
at mypackage.test.TestActivity.onCreate(TestActivity.java:23)
当然是
iDareYou.byteValue();
声明。明明是晴天!
我建议你一定要学会如何正确使用Dalvik Debug Monitor Server。
您发布的日志似乎毫无用处,您是否弄乱了一些 LogCat 过滤器(它发生在我身上一次)?
OFFTOPIC:“我在我的代码中的什么地方导致了异常?” - 我认为你的问题表述得不好。
我认为这个问题的正确名称可能是 - '如何使用 Android 调试器和 LogCat?一些异常没有正确记录!'
【讨论】:
感谢您的意见。我相信问题名称是合适的,因为我没有使用 LogCat 查看堆栈跟踪,我使用的是 Eclipse/ADT 中的调试窗口,我确实在问题名称中说明了这一点。您建议我可以使用 LogCat 解决最初的问题,这当然是正确的,但是我的问题是为什么 Eclipse/ADT 窗口似乎没有显示任何有用的堆栈跟踪。 在调试器挂起线程时,堆栈跟踪也没有显示在 LogCat 中,所以答案并不像我未能正确解释 LogCat 中显示的内容那么简单。【参考方案2】:iDareYou.byteValue();
如果要转换,在 Null-Value 上调用它会导致问题,我建议您尝试一下: Сonverting int to byte in android
【讨论】:
【参考方案3】:在 Eclipse 中,Android SDK 提供了几个视图。其中一个叫做“LogCat”。在那里你可以找到异常堆栈跟踪
【讨论】:
【参考方案4】:根据我的经验,Android 会吃掉膨胀布局时引起的异常。它当然应该报告异常,但显然一些 Android 开发人员遗憾地决定抓住它并创建一个新的——没有将前者添加为 cause。我认为这是Android环境的缺陷;因为它可能很难联系到我一直使用它的 Android 团队,但如果它真的困扰我,我会向 Google 报告。
【讨论】:
我认为这是真的,但在这种情况下并没有这样做。以上是关于Eclipse Android 调试器 - 我的代码在哪里导致异常?的主要内容,如果未能解决你的问题,请参考以下文章
Eclipse:为 Android 应用程序启动调试模式通常不起作用