不幸的是,我的应用程序已经停止。我该如何解决?

879

31
我看过许多类似的问题都被关闭了,理由是重复。这篇文章提供了帮助人们在问题中发布相关数据的好参考资料。但是,这并不是任何根本问题的重复,而只是挖掘根本问题的方法。我认为最好只提供这个问题的链接作为参考,而不要将其关闭为重复。 - laalto
39
我认为关闭功能很适合这个问题。大多数这些问题显示出对基本调试技能的了解很少。将它们暂时搁置提供了一个机会,让他们用回答中所述的方法澄清自己的问题。更好的是,他们可能能够自己解决问题。不过,这个讨论可能更适合 meta.stackoverflow.com。 - nhaarman
2
这个问题太模糊了。更好的问题应该是“使用[我的IDE],我如何调试一个显示错误消息'很抱歉,MyApp已停止运行'的Android应用程序?” - Chris Halcrow
9
@ChrisHalcrow,这个问题与调试没有任何关系。它是关于指导初学者如何处理应用程序崩溃的安卓问题。 - nhaarman
23个回答

776

本答案描述了检索堆栈跟踪的过程。已经有堆栈跟踪了吗?请参阅“什么是堆栈跟踪,如何使用它来调试应用程序错误?”中的堆栈跟踪。

问题

您的应用程序因未捕获的RuntimeException而退出。
最常见的是NullPointerException

如何解决?

每次Android应用程序崩溃(或任何Java应用程序),都会将Stack trace写入控制台(在此示例中为logcat)。此堆栈跟踪包含解决问题的重要信息。

Android Studio

Finding the stack trace in Android Studio

在窗口的底部栏中,点击Logcat按钮。或者,您可以按alt+6。确保您选择了模拟器或设备在Devices面板中。接下来,尝试找到堆栈跟踪,它显示为红色。可能有很多东西记录在logcat中,所以您可能需要滚动一下。查找堆栈跟踪的简单方法是清除logcat(使用右侧的回收站),然后让应用程序再次崩溃。

我找到了堆栈跟踪,现在怎么办?

太棒了!您已经解决了问题的一半。
您只需要通过分析堆栈跟踪找出究竟是什么导致了应用程序崩溃。

请阅读 "What is a stack trace, and how can I use it to debug my application errors?" 中的堆栈跟踪。

我仍然无法解决我的问题!

如果您已经找到了Exception和发生错误的行,但仍然无法弄清楚如何修复它,请毫不犹豫地在StackOverflow上提问。

尽可能简洁地发布堆栈跟踪和相关代码(例如,几行代码到抛出异常的那一行)。


42
我知道这篇帖子有点旧了,但如果你使用IntelliJ IDEA,你可以进入 Android > Devices|Logcat,然后添加一个新的过滤器(http://i.imgur.com/145dtkx.png),并将其过滤为“by Log Message”,在这里您可以输入“FATAL EXCEPTION”(http://i.imgur.com/HpELhaU.png),这样您就可以在此框中阅读应用程序抛出的所有异常。通过这种方法,您就不需要清除logcat并再次崩溃了。我认为Android Studio也具有此选项。 - Marco Acierno
1
在Eclipse中过滤logcat的方法是在筛选器的应用程序名称字段中输入Java包名称。 - Stephane
我认为主要的重点是理解当异常发生时所得到的回溯信息。 当没有回溯信息或者回溯信息无法使用时,FCs会有些糟糕,这就是问题变得棘手的地方。 但我认为这个解释是找到/识别此类错误的一个不错的入门介绍。 - DooMMasteR
4
当你的logcat有错误跟踪时,事情变得很容易,但如果logcat没有任何内容怎么办呢?https://dev59.com/pFwY5IYBdhLWcg3wlolg - Marian Paździoch
4
问题在于代码行中并未包含栈跟踪所指出的错误。 - Hilal
显示剩余2条评论

132
你可以使用Google的ADB工具获取Logcat文件以分析问题。
adb logcat > logcat.txt

打开 logcat.txt 文件并搜索您的应用程序名称。应该有关于失败原因、行号、类名等信息。

这很棒,它可以快速显示设备上发生的任何事情,即使您的调试器无法捕获它,对于 Xamarin 如果运行时加载失败可能会发生这种情况。 - Jerod Venema
1
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Yannick
1
你应该添加“-d”,否则你必须使用Ctrl-C退出logcat。我使用“adb logcat -v time -d > filename.txt”。 - Karakuri

45

首先,您需要检查应用程序在哪个点崩溃了(很抱歉,MyApp已停止)。为此,您可以使用Log.e("TAG", "Message");,使用该行代码,您可以在logcat中查看您的应用程序日志。

之后,您可以很容易地找到应用程序停止的位置,并解决问题。


36

只需检查log cat中的错误信息。

您可以在Eclipse中通过以下方法获取log cat:

窗口->显示视图->其他->Android->Logcat

Log cat中包含错误信息。

否则,您也可以通过以调试模式执行应用程序来检查错误。

首先设置断点,然后通过以下方式进行:

在项目上右键单击->Debug as->Android应用程序


34

注意:本答案使用的是Android Studio 2.2.2。

注意2:我假设您的设备已成功连接。


当您的应用程序崩溃时,您首先要做的是查看LogCat。在Android Studio底部有一个工具栏,其中包含一系列菜单:

image

点击“Android Monitor”(如上图所示下划线部分)。

现在,您将会看到以下内容:

image

更改“Verbose”为“Error”,然后它将仅显示已记录的错误。现在不要担心所有这些错误(如果您有它们)。

image

好的。现在,执行导致应用程序崩溃的操作。应用程序崩溃后,转到LogCat。您应该会找到一个新的崩溃日志,其中包含许多at:x.x.xCaused by:TrumpIsPresidentException等内容。转到您的logcat中的Caused by:语句。

image

Caused By:旁边,应该有发生的异常。在我的情况下,它是RuntimeException,并且在其下方应该有一行包含蓝色链接的文本,例如:

image

如果Caused by:后面没有带有蓝色文本的行,请查找另一个具有此信息的Caused by:

点击那个蓝色链接。它应该会带您到问题发生的位置。在我的情况下,问题是由于以下这行代码引起的:

throw new RuntimeException();

现在我知道为什么会崩溃了。因为我自己抛出了异常。这是一个明显的错误


不过,假设我遇到了另外一个错误:

java.lang.NullPointerException

我检查了我的logcat,点击了它给我的蓝色链接,然后它带我来到这里:

mTextView.setText(myString);

现在我想调试一下。根据这个StackOverflow问题的解答,NullPointerException表示某个东西是null

那么,我们来看看null是什么。有两种可能性,要么mTextView是空的,要么myString是空的。为了找出答案,在mTextView.setText(mString)代码行之前,我添加了下面这两行代码:

Log.d("AppDebug","mTextView is null: " + String.valueOf(mTextView == null);
Log.d("AppDebug","myString is null: " + String.valueOf(myString== null);

现在,就像我们之前所做的一样(我们将“Verose”更改为“Error”),我们想要将“Error”更改为“Debug”。因为我们正在通过调试记录日志。这里是所有的Log方法:

Log.
  d means Debug
  e means error
  w means warning
  v means verbose
  i means information
  wtf means "What a terrible failure". This is similar to Log.e

因此,由于我们使用了Log.d,所以我们正在检查调试状态。这就是为什么我们将其更改为debug的原因。

请注意,Log.d有一个第一个参数,在我们的情况下是“AppDebug”。在logcat顶部右侧的“No Filters”下拉菜单上单击。选择“编辑过滤器配置”,给您的过滤器命名,并在“日志标记”中放置“App Debug”。单击“确定”。现在,您应该在logcat中看到两行:

yourPackageNameAndApp: mTextView is null: true
yourPackageNameAndApp: myString is null: false

现在我们知道mTextView为空。

我观察了我的代码,现在注意到了一些问题。

我在类的顶部声明了private TextView mTextView,但是我没有定义它。

基本上,在我的onCreate()方法中忘记这样做了:

mTextView = (TextView) findViewById(R.id.textview_id_in_xml);

所以这就是为什么mTextView为空,因为我忘记告诉我的应用它是什么。所以我添加了那行代码,运行我的应用程序,现在应用程序不会崩溃了。


1
这是有用的信息,但是使用堆栈跟踪的图像会降低其实用性 - 图像无法搜索,无法复制和粘贴,无法被屏幕阅读器捕捉,并且更难以阅读。(顺便说一下,我没有投反对票,只是指出这一点)。 - EJoshuaS - Stand with Ukraine

23

当您的代码发生致命异常并停止应用程序执行时,此弹出窗口才会显示。这可能是任何异常,例如NullPointerExceptionOutOfMemoryException等。

如果您仍在使用Android Studio开发应用程序,则最好的方法是通过Logcat进行检查,这是快速阅读堆栈轨迹并检查应用程序原因的方式。

如果您的应用程序已经上线,则无法使用logcat。因此,为此,您可以实现Crashlytics,以提供任何异常的错误报告。


20

请检查您的Logcat消息并查看您的Manifest文件。应该有一些遗漏,例如定义Activity,用户权限等。


17
您可以使用以下任意工具:
  1. adb logcat

  2. adb logcat > logs.txt (您可以使用编辑器打开并搜索错误。)

  3. eclipse logcat (如果在eclipse中不可见,请转到Windows->显示视图->其他->Android->LogCat)

  4. Android Debug Monitor或Android Device Monitor (通过UI打开或输入命令monitor)

enter image description here

  1. Android Studio
我建议使用Android Debug Monitor,因为当日志太多时,eclipse会挂起,并且通过adb logcat筛选和查找都很困难。

13

您需要检查堆栈跟踪

如何做到这一点?

在您的IDE上,检查窗体LOGCAT

如果您无法看到logcat窗口,请转到此路径并打开它

window->show view->others->Android->Logcat

如果您正在使用Google API,请转到此路径。

adb logcat > logcat.txt


12

让我分享一下当您遇到 Force Close(应用程序停止工作)时的基本 Logcat 分析。

文档

Android 用于收集/分析日志的基本工具是 logcat。

此处是 Android 关于 logcat 的页面 链接

如果您使用的是 Android Studio,还可以查看此链接

捕获

基本上,您可以使用以下命令(或仅在 AndroidStudio 中检查 AndroidMonitor 窗口)手动捕获 logcat:

adb logcat

你可以添加许多参数到命令中,这有助于您过滤和显示您想要的消息……这是个人习惯问题...我总是使用下面的命令来获取消息时间戳:

adb logcat -v time

您可以将输出重定向到文件中,并在文本编辑器中进行分析。

分析

如果您的应用程序崩溃了,您会得到类似以下内容:

07-09 08:29:13.474 21144-21144/com.example.khan.abc D/AndroidRuntime: Shutting down VM
07-09 08:29:13.475 21144-21144/com.example.khan.abc E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.khan.abc, PID: 21144
    java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v4.app.FragmentActivity.onBackPressed()' on a null object reference
     at com.example.khan.abc.AudioFragment$1.onClick(AudioFragment.java:125)
     at android.view.View.performClick(View.java:4848)
     at android.view.View$PerformClick.run(View.java:20262)
     at android.os.Handler.handleCallback(Handler.java:815)
     at android.os.Handler.dispatchMessage(Handler.java:104)
     at android.os.Looper.loop(Looper.java:194)
     at android.app.ActivityThread.main(ActivityThread.java:5631)
     at java.lang.reflect.Method.invoke(Native Method)
     at java.lang.reflect.Method.invoke(Method.java:372)
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:959)
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:754)
07-09 08:29:15.195 21144-21144/com.example.khan.abc I/Process: Sending signal. PID: 21144 SIG: 9

这部分日志展示了很多信息:

  • 问题发生的时间:07-09 08:29:13.475

检查问题发生的时间非常重要…在一个日志中可能会有多个错误…你必须确定你正在检查正确的消息 :)

  • 崩溃的应用程序:com.example.khan.abc

这样,您就知道哪个应用程序崩溃了(以确保您正在检查关于您的消息的日志)

  • 发生的错误类型:java.lang.NullPointerException

一个空指针异常错误

  • 关于错误的详细信息:Attempt to invoke virtual method 'void android.support.v4.app.FragmentActivity.onBackPressed()' on a null object reference

您试图从一个FragmentActivity对象调用方法onBackPressed()。但是,在您执行此操作时,该对象为空。

  • 堆栈跟踪:堆栈跟踪向您展示方法调用的顺序…有时候,错误发生在调用方法而不是被调用方法中。

    at com.example.khan.abc.AudioFragment$1.onClick(AudioFragment.java:125)

错误发生在文件com.example.khan.abc.AudioFragment.java中,在onClick()方法内的第125行(堆栈跟踪显示了错误发生的行数)

它被以下内容调用:

at android.view.View.performClick(View.java:4848)

被称为:

at android.view.View$PerformClick.run(View.java:20262)

被称为:

at android.os.Handler.handleCallback(Handler.java:815)

概述

这只是一个概述... 并非所有的日志都是简单的,但错误会给出具体的问题,详细模式会显示全部问题... 这只是为了分享思路并向您提供入门级信息...

我希望我能在某种程度上帮助您... 敬礼


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