在 Android 上的 Eclipse 中调试有什么问题?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2552568/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 14:35:19  来源:igfitidea点击:

What's wrong with debugging in Eclipse on Android?

androideclipsedebugging

提问by Sebastian Dwornik

Possible Duplicate:
Seemingly useless debugging environment for Android

可能的重复:
Android 看似无用的调试环境

I've obviously been spoiled by Visual Studio, because although I'm just learning Android and the Eclipse environment, debugging apps in Eclipse is becoming a serious detriment to further development.

我显然已经被 Visual Studio 宠坏了,因为虽然我只是在学习 Android 和 Eclipse 环境,但在 Eclipse 中调试应用程序正成为对进一步开发的严重损害。

For example, Eclipse will compile this divide by zero just fine:

例如,Eclipse 将编译这个除以零就好了:

public class Lesson2Main extends Activity
{
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate (savedInstanceState);

        int i = 1 / 0;

        TextView tv = new TextView (this);
        tv.setText ("Hello, Android!");
        setContentView (tv);
    }
}

And then, when it executes it under the debugger, I will get a full screen of useless debug info, non of which actually points me to the specific line containing the error.

然后,当它在调试器下执行它时,我会得到一个无用的调试信息的全屏,其中没有实际将我指向包含错误的特定行。

The stackTrace is null within the exception ('e') info tree, and it simply states a message stating 'ArithmeticException'. (that's nice, how about you point me in the direction of where you found it!?)

异常 ('e') 信息树中的 stackTrace 为空,它只是声明一条消息,说明“ArithmeticException”。(太好了,你帮我指出你找到它的方向怎么样!?)

I've looked all over the screen and am baffled that this IDE can't get this right. Does developing with Eclipse resort everyone back to 1991 with printf() like logging at every interval then to track down bugs? Seriously.

我已经看遍了整个屏幕,但对这个 IDE 无法正确处理感到困惑。使用 Eclipse 进行开发是否会让每个人都回到 1991 年使用 printf() 喜欢在每个时间间隔记录然后跟踪错误?严重地。

Is there a configuration or plug-in that I'm missing to help with this?

是否有我缺少的配置或插件可以帮助解决这个问题?

I haven't tested this case with XCode, but if the iPhone dev. IDE handles this more like Visual Studio, then no wonder the Android marketplace has so few apps.

我还没有用 XCode 测试过这个案例,但如果是 iPhone 开发者。IDE 处理这个更像 Visual Studio,难怪 Android 市场的应用程序很少。

I'm excited about Android, but it seems that Eclipse is getting in the way.

我对 Android 感到很兴奋,但似乎 Eclipse 正在妨碍我。

采纳答案by Steve Haley

Yes, you've missed one of the very important plug-ins for Eclipse called "LogCat". It catches all the debugging logs that your Android program gives, whether it's running on the Emulator or a real phone. The latter obviously requires that the phone be plugged in to the computer, and less-obviously, the setting in Application -> Development -> Enable USB Debugging be enabled.

是的,您已经错过了一个非常重要的 Eclipse 插件“LogCat”。它会捕获您的 Android 程序提供的所有调试日志,无论它是在模拟器上运行还是在真实手机上运行。后者显然需要将手机插入电脑,不太明显的是,在应用程序->开发->启用USB调试中的设置被启用。

The LogCat messages give you the full breakdown of what caused the error, including the line number. To open LogCat in Eclipse, go to Window -> Show View -> Other -> Android (one of the folders in the list) -> LogCat. Then dock the LogCat window somewhere where you can see it easily, and Eclipse will remember that location and open it up again next time your start it.

LogCat 消息为您提供了导致错误的原因的完整分类,包括行号。要在 Eclipse 中打开 LogCat,请转到 Window -> Show View -> Other -> Android(列表中的文件夹之一)-> LogCat。然后将 LogCat 窗口停靠在您可以轻松看到的某个位置,Eclipse 将记住该位置并在您下次启动它时再次打开它。

(Sometimes LogCat and the Emulator get disconnected from each other. The simple way to fix that is just to close Eclipse and the emulator, then restart them both.)

(有时 LogCat 和模拟器会相互断开连接。解决这个问题的简单方法就是关闭 Eclipse 和模拟器,然后重新启动它们。)

回答by fadden

(There's too much to say in a comment, so I'm writing this up as an answer.)

(评论中有太多话要说,所以我将其写下来作为答案。)

You can configure Eclipse to stop on exceptions that are caught, uncaught, or both. By default, Eclipse will break on any uncaught exception, and will ignore all caught exceptions (i.e. anything that is snagged by a try/catch block).

您可以将 Eclipse 配置为在捕获、未捕获或两者兼有的异常时停止。默认情况下,Eclipse 将中断任何未捕获的异常,并忽略所有捕获的异常(即任何被 try/catch 块捕获的异常)。

Things get a little weird for Android because you're running in an application framework, not a stand-alone application. As you can see from the stack trace posted above, the exception was actually caught by ActivityThread. This means that your initial exception is considered "caught", and won't trip Eclipse's break-on-uncaught handling until ActivityThread re-throws it. For this reason, the stack you see in the debugger when it stops is nowhere near your code.

Android 的情况有些奇怪,因为您在应用程序框架中运行,而不是在独立应用程序中运行。从上面发布的堆栈跟踪中可以看出,异常实际上是由 ActivityThread 捕获的。这意味着您的初始异常被视为“已捕获”,并且在 ActivityThread 重新抛出它之前不会触发 Eclipse 的中断处理。出于这个原因,您在调试器停止时看到的堆栈与您的代码相距甚远。

Since you know you're getting an ArithmeticException, you can have it break on "caught" instances of that exception, and it will stop at the point of the throw. (Don't have it break on all caught exceptions -- you'll be hitting "resume" endlessly.)

由于您知道您收到了 ArithmeticException,您可以让它在该异常的“捕获”实例上中断,并且它会在抛出点停止。(不要让它在所有捕获的异常上中断——你会无休止地点击“恢复”。)

As far as the logging being "late", if the debugger let the program continue to execute until the logging happened, you wouldn't be able to debug at the point of the throw.

至于日志记录“迟到”,如果调试器让程序继续执行直到日志记录发生,您将无法在抛出点进行调试。

回答by Janusz

I get the following stack trace in logcat:

我在 logcat 中得到以下堆栈跟踪:

03-31 17:01:11.272: ERROR/AndroidRuntime(205): java.lang.RuntimeException: Unable to start activity ComponentInfo{MyClass}: java.lang.ArithmeticException: divide by zero
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2401)
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2417)
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at android.app.ActivityThread.access00(ActivityThread.java:116)
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1794)
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at android.os.Handler.dispatchMessage(Handler.java:99)
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at android.os.Looper.loop(Looper.java:123)
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at android.app.ActivityThread.main(ActivityThread.java:4203)
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at java.lang.reflect.Method.invokeNative(Native Method)
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at java.lang.reflect.Method.invoke(Method.java:521)
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:549)
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at dalvik.system.NativeStart.main(Native Method)
03-31 17:01:11.272: ERROR/AndroidRuntime(205): Caused by: java.lang.ArithmeticException: divide by zero
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at MyClass.onCreate(MyClass.java:40)
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1123)
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2364)
03-31 17:01:11.272: ERROR/AndroidRuntime(205):     ... 11 more

This is crystal clear. Look at the causing exception in line 14 of the stack trace and it says: Divide by zero. That is what you have done wrong. The next line says: at MyClass.onCreate(MyClass.java:40) This would be the line the exception occurs in. I don't get what would be difficult, or useless about this. How would VS present this?

这是非常清楚的。查看堆栈跟踪第 14 行中导致的异常,它说:除以零。那就是你做错了。下一行说: at MyClass.onCreate(MyClass.java:40) 这将是发生异常的那一行。我不明白这有什么困难,或无用。VS 将如何呈现?

回答by Frank LaRosa

For weeks after starting Android development, I was frustrated by the lack of information I found in the LogCat window. I would put Log messages in my app and never see them, and I knew my app was throwing exceptions but I never saw those either.

在开始 Android 开发后的几个星期里,我对在 LogCat 窗口中找不到的信息感到沮丧。我会将日志消息放在我的应用程序中,但永远不会看到它们,我知道我的应用程序正在抛出异常,但我也从未看到它们。

Finally one day I figured it out: my LogCat window was showing the wrong device. I usually have two or three Android devices connected to my computer at any given time, and LogCat was showing one of those other devices. To change this you have to display the Devices window and select the device you want in that window.

终于有一天我弄明白了:我的 LogCat 窗口显示了错误的设备。我通常在任何给定时间都有两到三台 Android 设备连接到我的计算机,而 LogCat 显示的是其他设备之一。要更改此设置,您必须显示“设备”窗口并在该窗口中选择所需的设备。

I find this to be an example of laughably bad UI. Here I am looking at a LogCat window and nowhere in that window is there any indication as to what device's logs I'm looking at. I have to know enough to open a totally different window and select the device there. I literally wasted weeks of time before I figured this out. You'd think that LogCat would default to all devices, or at least, automatically switch to the device you most recently launched an app on, but it doesn't. If you are banging your head against your desk wondering why LogCat is so useless, maybe this is why.

我发现这是一个可笑的糟糕 UI 的例子。在这里,我正在查看 LogCat 窗口,但在该窗口中没有任何迹象表明我正在查看哪些设备的日志。我必须足够了解才能打开一个完全不同的窗口并在那里选择设备。在我弄清楚这一点之前,我真的浪费了几周的时间。您可能认为 LogCat 会默认使用所有设备,或者至少会自动切换到您最近启动应用程序的设备,但事实并非如此。如果您正用头撞着桌子想知道为什么 LogCat 如此无用,也许这就是原因。

回答by Steve

You are experiencing a typical problem of developing with a physical device as opposed to a piece of software on a machine.

您遇到了使用物理设备而不是机器上的软件进行开发的典型问题。

It will point you to the specific error (Post the info and we can show you) Just look for your package names in the error it will show where the exception was thrown.

它将指向您特定的错误(发布信息,我们可以向您展示)只需在错误中查找您的包名称,它就会显示引发异常的位置。

You should also use breakpoints to step through the process and see what happens the DDMS debugger should meet all your needed requirements.

您还应该使用断点来逐步完成整个过程,看看 DDMS 调试器应该满足您所有需要的要求会发生什么。

And yes you should use logging Log.i(TAG, "Info: " + x);

是的,您应该使用日志记录 Log.i(TAG, "Info: " + x);

You can't predict everything that happens and as your code base grows you will be glad you started doing this early.

您无法预测发生的一切,随着代码库的增长,您会很高兴自己早早开始这样做。