首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在Android中设置全局未捕获异常处理器的理想方式

在Android中设置全局未捕获异常处理器的理想方式
EN

Stack Overflow用户
提问于 2010-05-04 18:12:52
回答 4查看 45.5K关注 0票数 89

我想为我的Android应用程序中的所有线程设置一个全局未捕获的异常处理程序。因此,在我的Application子类中,我将Thread.UncaughtExceptionHandler的一个实现设置为未捕获异常的默认处理程序。

代码语言:javascript
复制
Thread.setDefaultUncaughtExceptionHandler(
                new DefaultExceptionHandler(this));

在我的实现中,我尝试显示一个AlertDialog,显示适当的异常消息。

然而,这似乎不起作用。无论何时,任何未处理的线程都会抛出异常,我就会看到stock,OS-default对话框(“对不起!-应用程序-已停止-意外对话框”)。

为未捕获的异常设置默认处理程序的正确且理想的方法是什么?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-05-05 05:04:59

这应该就是您需要做的全部工作。(确保之后导致进程停止--事情可能处于不确定的状态。)

首先要检查的是Android处理程序是否仍在被调用。有可能您的版本正在被调用,但却致命地失败了,当system_server看到进程崩溃时,它会显示一个通用对话框。

在您的处理程序的顶部添加一些日志消息,以查看它是否到达那里。打印来自getDefaultUncaughtExceptionHandler的结果,然后抛出一个未捕获的异常以导致崩溃。密切关注logcat输出,看看发生了什么。

票数 24
EN

Stack Overflow用户

发布于 2015-01-24 22:25:08

我很久以前就发布了用于自定义处理安卓崩溃的简单solution。这有点老生常谈,但它适用于所有Android版本(包括棒棒糖)。

首先是一个小小的理论。在Android中使用未捕获的异常处理程序时,主要问题是主线程(也称为UI)中抛出的异常。这就是为什么。当应用程序启动时,系统调用准备并启动应用程序Main looperActivityThread.main方法:

代码语言:javascript
复制
public static void main(String[] args) {
  …
  …
    Looper.prepareMainLooper();
  …
    Looper.loop();
    throw new RuntimeException("Main thread loop unexpectedly exited");
}

主循环负责处理发布在UI线程中的消息(包括与UI呈现和交互相关的所有消息)。如果在UI线程中抛出异常,它将被您的异常处理程序捕获,但是由于您的loop()方法已用完,您将无法向用户显示任何对话框或活动,因为没有人为您处理UI消息。

建议的解决方案非常简单。我们自己运行Looper.loop方法,并用try-catch代码块包围它。当捕获到异常时,我们会根据需要对其进行处理(例如,启动我们的自定义报告活动),然后再次调用Looper.loop方法。

下面的方法演示了这种技术(应该从Application.onCreate侦听器中调用):

代码语言:javascript
复制
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);
        }
    }
}

如您所见,未捕获的异常处理程序仅用于后台线程中抛出的异常。下面的处理程序捕获这些异常并将它们传播到UI线程:

代码语言:javascript
复制
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存储库中提供了一个使用此技术的示例项目:https://github.com/idolon-github/android-crash-catcher

票数 13
EN

Stack Overflow用户

发布于 2010-05-04 23:11:47

我认为要在uncaughtException()方法中禁用该功能,请不要调用previousHandler.uncaughtException(),因为previousHandler是由

代码语言:javascript
复制
previousHandler = Thread.getDefaultUncaughtExceptionHandler();
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2764394

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档