Sam*_*muh 85 android exception-handling uncaught-exception
我想为我的Android应用程序中的所有线程设置一个全局未捕获的异常处理程序.所以,在我的Application子类中,我Thread.UncaughtExceptionHandler为未捕获的异常设置了默认处理程序的实现.
Thread.setDefaultUncaughtExceptionHandler(
new DefaultExceptionHandler(this));
Run Code Online (Sandbox Code Playgroud)
在我的实现中,我试图显示一个AlertDialog显示适当的异常消息.
但是,这似乎不起作用.无论何时,对于任何未处理的线程抛出异常,我都会获得库存操作系统默认对话框("抱歉!-Application-have-stopped-unexpectedly dialog").
为未捕获的异常设置默认处理程序的正确和理想方法是什么?
fad*_*den 24
这应该就是你需要做的.(确保你事后停止进程 - 事情可能处于不确定状态.)
要检查的第一件事是Android处理程序是否仍然被调用.可能是您的版本被调用但是致命失败并且system_server在看到进程崩溃时显示通用对话框.
在处理程序的顶部添加一些日志消息,看它是否到达那里.从getDefaultUncaughtExceptionHandler打印结果,然后抛出未捕获的异常以导致崩溃.密切关注logcat输出,看看发生了什么.
Ido*_*lon 11
我很久以前发布了Android崩溃自定义处理的简单解决方案.它有点hacky但它适用于所有Android版本(包括Lollipop).
首先是一点理论.在Android中使用未捕获的异常处理程序时的主要问题是在主(也称为UI)线程中引发的异常.这就是原因.当应用程序启动系统时调用ActivityThread.main方法,该方法准备并启动应用程序的主循环器:
public static void main(String[] args) {
…
…
Looper.prepareMainLooper();
…
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
Run Code Online (Sandbox Code Playgroud)
主循环器负责处理UI线程中发布的消息(包括与UI呈现和交互相关的所有消息).如果在UI线程中抛出异常,它将被您的异常处理程序捕获,但由于您没有loop()方法,您将无法向用户显示任何对话或活动,因为没有人可以处理UI消息为了你.
建议的解决方案非常简单.我们Looper.loop自己运行方法并用try-catch块包围它.当捕获到异常时,我们会根据需要处理它(例如,启动我们的自定义报告活动)并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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
如您所见,未捕获的异常处理程序仅用于后台线程中抛出的异常.以下处理程序捕获这些异常并将它们传播到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);
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
我的GitHub存储库中提供了使用此技术的示例项目:https://github.com/idolon-github/android-crash-catcher
| 归档时间: |
|
| 查看次数: |
42157 次 |
| 最近记录: |