在Android中设置全局未捕获的exception处理程序的理想方法
我想为我的Android应用程序中的所有线程设置全局未捕获的exception处理程序。 所以,在我的Application
子类中,我将Thread.UncaughtExceptionHandler
的实现设置为未捕获exception的默认处理程序。
Thread.setDefaultUncaughtExceptionHandler( new DefaultExceptionHandler(this));
在我的实现中,我试图显示一个AlertDialog
显示适当的exception消息。
但是,这似乎并不奏效。 无论何时,任何未处理的线程都会抛出exception,我得到股票,操作系统默认对话框(“Sorry!-Application-has-stopped-unexpectedly dialog”)。
什么是正确和理想的方式来设置未捕获的exception的默认处理程序?
这应该是你需要做的一切。 (确保你之后会导致进程停顿 – 事情可能处于一个不确定的状态。)
首先要检查的是Android处理程序是否仍然被调用。 可能是你的版本被调用,但是失败致命,system_server在看到进程崩溃时显示一个通用对话框。
在处理程序的顶部添加一些日志消息,看看它是否到达那里。 从getDefaultUncaughtExceptionHandler打印结果,然后抛出未捕获的exception以导致崩溃。 关注logcat输出,看看发生了什么事情。
我发布了自定义处理Android崩溃的简单解决scheme很久以前。 这是一个小黑客,但它适用于所有的Android版本(包括棒棒糖)。
首先是一点理论。 在Android中使用未捕获的exception处理程序时遇到的主要问题是在主(又名UI)线程中抛出的exception。 这是为什么。 当应用程序启动系统调用ActivityThread.main方法准备并启动您的应用程序的主循环 :
public static void main(String[] args) { … … Looper.prepareMainLooper(); … Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }
主要looper负责处理UI线程中发布的消息(包括所有与UI呈现和交互相关的消息)。 如果在UI线程中引发exception,它将被exception处理程序捕获,但由于您不在loop()
方法中,因此无法向用户显示任何对话框或活动,因为没有人留给为您处理UI消息。
build议的解决scheme非常简单。 我们自己运行Looper.loop
方法,并用try-catch块来包围它。 当一个exception被捕获时,我们按照我们的要求处理它(例如,开始我们的自定义报告活动)并再次调用Looper.loop
方法。
以下方法演示了这种技术(它应该从Application.onCreate
侦听器中调用):
private void startCatcher() { UncaughtExceptionHandler systemUncaughtHandler = Thread.getDefaultUncaughtExceptionHandler(); // the following handler is used to catch exceptions thrown in background threads Thread.setDefaultUncaughtExceptionHandler(new UncaughtHandler(new Handler())); while (true) { try { Looper.loop(); Thread.setDefaultUncaughtExceptionHandler(systemUncaughtHandler); throw new RuntimeException("Main thread loop unexpectedly exited"); } catch (Throwable e) { showCrashDisplayActivity(e); } } }
正如您所看到的,未捕获的exception处理程序仅用于在后台线程中抛出的exception。 以下处理程序捕获这些exception并将其传播到UI线程:
static class UncaughtHandler implements UncaughtExceptionHandler { private final Handler mHandler; UncaughtHandler(Handler handler) { mHandler = handler; } public void uncaughtException(Thread thread, final Throwable e) { mHandler.post(new Runnable() { public void run() { throw new BackgroundException(e); } }); } }
使用这种技术的示例项目可以在我的GitHub仓库中find: https : //github.com/idolon-github/android-crash-catcher
FWIW我知道这有点偏离主题,但我们一直在使用Crittercism的成功免费计划 。 他们还提供一些高级function,如处理exception,以便应用程序不会崩溃。
在免费版本,用户仍然看到崩溃,但至less我得到的电子邮件和堆栈跟踪。
我们也使用iOS版本(但是我从同事那里听说,它不太好)。
这里有类似的问题:
- 全局未捕获exception处理程序 – >电子邮件日志给我?
- 是否有可能在Android中创build某种全局exception处理程序?
我想在你的uncaughtException()方法中禁用这个,不要调用previousHandler.uncaughtException(),其中previousHandler是由
previousHandler = Thread.getDefaultUncaughtExceptionHandler();
在你打电话之前它不工作
android.os.Process.killProcess(android.os.Process.myPid());
在你的UncaughtExceptionHandler的最后。
- 我怎样才能在PHP中处理file_get_contents()函数的警告?
- .NET中的java.lang.IllegalStateException?
- 如果您在“我们不使用例外”阵营,那么您如何使用标准库?
- Spring Boot REST服务exception处理
- c ++exception:抛出std :: string
- 处理dynamic时引发大量的Microsoft.CSharp.RuntimeBinderExceptions
- 在C#中访问Process.MainModule.FileName时如何避免Win32exception?
- 并发修改exception:添加到ArrayList
- 不可捕捉的ChuckNorrisException