如何在Eclipse中调试Android

6
请尝试以下步骤:
  1. 创建一个 HelloWorld 应用。

  2. 在 onCreate 的结尾添加一个 Log 语句:

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        Log.d("HelloWorldActivity.onCreate()", "setContentView() completed");
    }
  1. 在 Log 语句上放置断点。

  2. 在模拟器中运行该应用程序,并注意它是否可以正常工作,通过单步执行查看 Eclipse 的 LogCat 窗口中的已记录条目。

  3. 将 HelloWorldActivity 更改为扩展 ListActivity 而不是 Activity。

    public class HelloWorldActivity extends ListActivity {
    
  4. 再次在模拟器中运行应用程序,注意它无法到达 Log 语句。

我的问题不是为什么会失败,而是您如何调试此错误?我在 Eclipse 的调试窗格中只看到一个 RuntimeException。我看到 LogCat 有一堆消息,但它太大了,我已经搜索过它,但找不到任何指示出错或异常发生位置的内容。我找不到一种方法来显示 RuntimeException 内部的消息或堆栈跟踪,以知道哪行代码引发了异常。

我假设必须有更好的方法使用工具来查找错误,但我是初学者,在没有使用 try/catch 包装编码的所有内容的情况下,似乎无法找到更好的调试方法。我希望在 LogCat 中找到由抛出异常生成的消息。我希望调试窗口允许您检查异常的内容。我不是说这样的技术不存在,我是说作为初学者,我难以弄清楚如何调试并询问存在哪些技术以及如何使用它们?

因此,简而言之:

  • 如果您不知道其原因,您将如何找到此错误?
  • 您将使用哪些技术来查找根本原因?
  • 您将如何检查异常的详细信息?
  • 通常,您如何使用 Eclipse 在 Android 代码中查找问题?

欢迎提出多种建议和讨论。

我本可以包含我的 LogCat 内容,但它太大了,不合理。您应该可以轻松重现此问题,因此我将其省略。可能有一些 LogCat 内容可供我使用,但它非常大,即使运行小程序也很大,因此需要提示要搜索什么以及如何在从 API 调用抛出异常时解释它。我看到其他帖子说 LogCat 中应该有一些内容,虽然可能是真的,但我自己找不到任何东西。如果您认为 LogCat 应该有内容,请自己运行测试,并将您所需找到的行复制到响应中。

谢谢。

迄今为止,总结的技术列表如下:

侵入式技术: 1. 在希望查看执行位置的代码中放置Toast。 2. 在可能抛出异常的代码周围放置try/catch。 3. 注释掉代码并重新编译和测试。

非侵入式技术: 1. 使用调试器。断点、变量检查等。 2. Monkey压力测试工具。 3. 下载Android源库。 4. 使用LogCat过滤器查看是否列出了“Caused By”。

不确定是否可用: 1. Android库的调试版本,其中包含额外的日志记录、断言或其他额外的帮助。 2. 通过调试窗格或其他技术在Eclipse中检查异常的方法。 3. 定义更全局的try/catch异常处理程序的方法。 4. 能够通过Android库源代码进行调试的能力。

不可用: 1. 一种非侵入式的查看异常内容或异常发生位置的方法。


为了检查异常细节,我经常在调试模式下使用表达式窗口(Window>Show View>Expressions)来检查值。当检查异常时,这非常方便,因为exception.getMesage()并不总是返回消息(即null)。在断点处的调试模式中右键单击变量,然后选择“watch”。您必须跨越异常才能观察它。 - Emile
在Eclipse中,问题窗口将显示预编译时错误和严格警告。(窗口>显示视图>其他...>问题) - Emile
LogCat一开始是误导人的。过滤器作用于消息而不是日志标签。要创建自定义过滤器,您应该使用LogCat菜单并选择“创建过滤器”选项。在这里,您可以按标签和pid进行过滤,从而获得更精细的控制。它还出现在一个选项卡窗口中。非常有用,可以隐藏系统事件。这些消息确实有助于了解上次工作的情况,但可能不会显示错误。因此,切换回显示所有系统事件(或按pid记录)。 - Emile
4个回答

2

嘿,有趣的问题。首先,你可以过滤logcat告诉你的信息。例如,你可以通过点击红色(e)使其只显示错误信息。 如果以调试模式运行应用程序,则它还会告诉您发生错误的位置。它可以直接指向您的代码或安卓SDK。了解造成错误的安卓软件包是一个很大的帮助。

这两个想法突然浮现在我脑海中,希望对你有所帮助!


是的,红色(e)似乎起到了过滤作用,这非常有帮助。你知道异常是否应该记录错误、警告或信息吗?因为我没有看到任何东西,所以不确定它应该是什么样子。如果是错误,你的建议将显著减少消息数量。 - user405821
关于“调试模式”。这只是您单击错误图标而不是简单运行的地方,还是我应该加载一些调试库。我更多地是Windows程序员,当我使用MFC时,它们有一个库的调试版本,因此您实际上可以跟踪源代码。在Android / Eclipse中是否有类似的东西? - user405821
我想给你点赞,但显然我需要更高的评级才能这样做。很抱歉。:( - user405821

1

我遇到了同样的问题,并找到了Steve H提供的以下解决方案:

问题在于当调试器附加时,异常日志不会被发布到LogCat,直到您从Debug视图中终止应用程序。这是因为应用程序直到调试器分离才会崩溃。- Steve H Mar 31 at 15:47

------ 是的,就是这样。现在我看到了相同的异常。在我让程序运行完整个崩溃和退出过程之后。它应该在停止我的程序并打开IDE调试器屏幕时显示该信息。而不是让我疑惑并浪费时间进行更多的点击。Eclipse似乎还有很长的路要走才能与Visual Studio等竞争。希望我的耐心能够超过我的项目。感谢反馈。:) - Sebastian Dwornik Mar 31 at 17:35

问题链接:在Android上使用Eclipse调试有什么问题?


0

没有使用try/catch捕获的异常是错误,会打破程序的正常流程。

在调试模式下运行只需点击“bug”按钮。我不知道是否有任何“特殊”的调试库。但是在使用Android时,所有“库”都是开源的,因此您几乎可以查看任何内容。

调试模式的好处是当出现错误时,您的应用程序会在错误发生时被冻结在中间状态。您可以设置断点,在程序运行时即时更改代码,这非常棒(当然,您不能进行重大更改,例如更改方法名称)。

然而,在处理Android中的错误和故障时,与.NET有所不同,因为每个模型都不同。

在编写 Windows 应用程序时,应用程序就像小岛一样独立运行。您可以对代码流程有更直接的控制(例如:您可以调用模态对话框来冻结代码流程,同时用户输入数据),并且您可以使用一个线程制作完全功能的程序。 在 Android 中,几乎所有东西都在其自己的同步中运行。您的应用程序必须准备处理像在执行过程中接收电话这样的情况。因此,您也可以将此模型应用于调试:(由于意外情况而发生的)错误往往比其他开发环境中更容易传播。处理这些错误的方式也不同:这在您意识到即使抛出异常,您的应用程序仍然运行时就会显现出来。
一些更有用的提示: 您有一个非常强大的工具——Monkey,它是一种压力测试工具,可以生成“伪随机的用户事件流,例如点击、触摸或手势,以及许多系统级事件”。
LogCat 可以指示错误的“原因”。该行通常以 Caused By 开始。如果您对原因而不是后果感兴趣,可以进一步过滤错误报告,寻找“Caused by”。
最后但并非最不重要的,我发现注释代码行并观察其结果的旧方法对于解决问题非常有用。
希望这能帮到你。

是的,我在另一篇帖子中看到了“Caused By”,但当我在我的LogCat中搜索它时,它没有显示出来。你试过我的例子,看看是否会为你出现“Caused By”吗?我很好奇是否应该看到我错过的东西。 - user405821
在我的示例中,当错误发生时,似乎我的代码并没有被冻结。看起来异常被抛出了,由于我没有异常处理程序,所以我的代码只是在日志语句之后退出了。也许我错过了调试器中可用的某些设置(例如“异常中断”)? - user405821
注释掉代码行是一个好的建议。我一直在这样做。有点慢和繁琐,但绝对有效。一旦我收集到这篇文章的所有建议,我会把它们汇总起来。也许我会重新发布到博客或其他地方与他人分享。谢谢 :) - user405821
在您的特定代码中,程序停留在第一个创建的活动main。因此,只有super.onCreate(savedInstanceState);被运行。请尝试以下操作:(1)创建一个新项目(2)在main中添加2个按钮(3)创建另一个带有一些错误的活动(4)将一个按钮绑定到第二个活动(5)将第二个按钮绑定到Toat.makeText(6)运行应用程序并单击第一个按钮...将会出现一个错误。一个警报将出现,您点击OK,您的应用程序将继续运行,如果您点击按钮2,它将起作用。如果您的按钮2也使用了某种来自活动2的返回,则这也是有效的。 - Tivie

0
通常,如果任何事情引发异常,那么您可能应该为该情况提供支持,但是放置try/catch块是找到特定问题的不错方式。 我发现,如果您不在catch块中放置任何内容,则无法在eclipse的观察变量窗口中评估异常。因此,我总是在其中放置一个Log调用,并在该行上设置断点。
public void onCreate(Bundle savedInstanceState) {
    try{
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }catch(Exception exception)
    {
        // put break point on line below so you can evaluate exception in debug mode.
        Log.e(TAG, "Set content exception "+ exception.getMessage());
        // note some exceptions return null on getMessage();
    }
    Log.d("HelloWorldActivity.onCreate()", "setContentView() completed");
}

如果你的堆栈跟踪很大,那么这将有所帮助。其他开发人员也发现获取sdk的源代码意味着你可以查看错误在主sdk代码中抛出的位置。不过我还没有这样做。


有源代码会很有帮助。非常有帮助!我知道它是可用的,但不确定你是否可以使用调试器来跟踪它。那将非常有帮助。是否有关于如何将其整合到调试会话中的说明? - user405821
我理解你的观点,即在可能引发异常的任何内容周围都要加上try/catch。然而,在编写测试代码时,每个小代码段周围都加上这个非常麻烦,而且只是为了掌握基础知识。此外,如果你读了我的情况,一旦代码被修复,那个异常就不应该再发生了。同样,这是找到问题的技巧之一。那么,有没有办法在不添加try/catch代码的情况下获取异常的内容呢? - user405821
如果进行测试代码,请将所有代码放在一个try catch中,然后添加更多特定情况的try catch来进行管理。至少这样,在抛出异常时可以节省时间,并且不需要太多的努力。 - Emile
你如何使用单个try/catch来覆盖所有内容?由于大多数代码都在回调函数中,因此我不清楚在哪里可以放置这样的代码,以充当所有未捕获异常的后备。如果这是Windows/C++,我会将其添加到我的main()函数中,并/或者使用set_unexpected()和其他类似的API安装全局异常处理程序来设置错误处理程序。 - user405821
据我所知,你不能用try catch来捕获所有异常。但是你可以在特定的方法中加上try catch语句来捕获异常。 - Emile
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接