在Android中设置全局未捕获异常处理程序的理想方法
我想为 Android 应用程序中的所有线程设置一个全局未捕获异常处理程序。因此,在我的 Application
子类中,我将 Thread.UncaughtExceptionHandler
的实现设置为未捕获异常的默认处理程序。
Thread.setDefaultUncaughtExceptionHandler(
new DefaultExceptionHandler(this));
在我的实现中,我尝试显示一个 AlertDialog
来显示适当的异常消息。
然而,这似乎不起作用。每当任何未处理的线程抛出异常时,我都会收到股票操作系统默认对话框(“抱歉!应用程序意外停止对话框”)。
为未捕获的异常设置默认处理程序的正确且理想的方法是什么?
I want to set a global uncaught exception handler for all the threads in my Android application. So, in my Application
subclass I set an implementation of Thread.UncaughtExceptionHandler
as default handler for uncaught exceptions.
Thread.setDefaultUncaughtExceptionHandler(
new DefaultExceptionHandler(this));
In my implementation, I am trying to display an AlertDialog
displaying appropriate exception message.
However, this doesn't seem to work. Whenever, an exception is thrown for any thread which goes un-handled, I get the stock, OS-default dialog ("Sorry!-Application-has-stopped-unexpectedly dialog").
What is the correct and ideal way to set a default handler for uncaught exceptions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
这应该就是您需要做的全部。 (确保随后让进程停止——事情可能处于不确定状态。)
首先要检查的是 Android 处理程序是否仍在被调用。您的版本可能正在被调用,但严重失败,并且 system_server 在看到进程崩溃时显示通用对话框。
在处理程序的顶部添加一些日志消息以查看它是否到达那里。打印 getDefaultUncaughtExceptionHandler 的结果,然后抛出未捕获的异常导致崩溃。密切关注 logcat 输出以了解发生了什么。
That should be all you need to do. (Make sure you cause the process to halt afterward -- things could be in an uncertain state.)
The first thing to check is whether the Android handler is still getting called. It's possible that your version is being called but failing fatally and the system_server is showing a generic dialog when it sees the process crash.
Add some log messages at the top of your handler to see if it's getting there. Print the result from getDefaultUncaughtExceptionHandler and then throw an uncaught exception to cause a crash. Keep an eye on the logcat output to see what's going on.
我很久以前发布了用于自定义处理 Android 崩溃的简单解决方案。虽然有点老套,但它适用于所有 Android 版本(包括 Lollipop)。
首先介绍一点理论。在 Android 中使用未捕获的异常处理程序时,主要问题是在主(又名 UI)线程中抛出异常。这就是原因。当应用程序启动系统调用 ActivityThread.main 方法,用于准备并启动 Main Looper of your app:
Main Looper 负责处理 UI 线程中发布的消息(包括所有与 UI 渲染相关的消息)和互动)。如果 UI 线程中抛出异常,它将被异常处理程序捕获,但由于您超出了
loop()
方法,因此您将无法向该线程显示任何对话框或活动。用户,因为没有人可以为您处理 UI 消息。所提出的解决方案非常简单。我们自己运行
Looper.loop
方法,并用 try-catch 块包围它。当捕获到异常时,我们根据需要对其进行处理(例如启动自定义报告活动)并再次调用 Looper.loop 方法。以下方法演示了此技术(应从
Application.onCreate
侦听器调用):如您所见,未捕获的异常处理程序仅用于后台线程中引发的异常。以下处理程序捕获这些异常并将它们传播到 UI 线程:
我的 GitHub 存储库上提供了使用此技术的示例项目:
I posted the simple solution for custom handling of Android crashes a long ago. It's a little hacky however it works on all Android versions (including the Lollipop).
First a little bit of theory. The main issues when you use uncaught exception handler in Android come with the exceptions thrown in the main (aka UI) thread. And here is why. When the app starts system calls ActivityThread.main method which prepares and starts the Main looper of your app:
Main looper is responsible for processing messages posted in the UI thread (including all messages related to UI rendering and interaction). If an exception is thrown in the UI thread it will be caught by your exception handler, but since you're out of
loop()
method you won't be able to show any dialog or activity to the user as there's no one left to process UI messages for you.The proposed solution is quite simple. We run
Looper.loop
method by our own and surround it with try-catch block. When an exception is caught we process it as we want (for example start our custom report activity) and callLooper.loop
method again.The following method demonstrates this technique (it should be called from the
Application.onCreate
listener):As you can see the uncaught exception handler is used only for the exceptions thrown in background threads. The following handler catches those exceptions and propagates them to the UI thread:
An example project which uses this technique is available on my GitHub repo: https://github.com/idolon-github/android-crash-catcher
我认为要在 uncaughtException() 方法中禁用它,请不要调用 previousHandler.uncaughtException() ,其中 previousHandler 设置为
I think to disable that in your uncaughtException() method do not call previousHandler.uncaughtException() where previousHandler is set by
FWIW 我知道这有点偏离主题,但我们一直在使用 Crittercism 的免费计划成功。它们还提供一些高级功能,例如处理异常,以免应用程序崩溃。
在免费版本中,用户仍然会看到崩溃,但至少我收到了电子邮件和堆栈跟踪。
我们也使用 iOS 版本(但我听同事说它不太好)。
以下是类似的问题:
FWIW I know this is slightly off-topic, but we've been using Crittercism's free plan with success. They also offer some premium features, like handling the exception so the app doesn't crash.
In the free version, the user still sees the crash, but at least I get the email and the stack trace.
We also use the iOS version (but I've heard from my colleagues that it is not quite as good).
Here are similar questions:
调用它才起作用。
直到您在 UncaughtExceptionHandler 的最后
It doesn't work until you call
at the very end of your UncaughtExceptionHandler.