Android中设置全局未捕获的异常处理程序的理想方法

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

Thread.setDefaultUncaughtExceptionHandler(
                new DefaultExceptionHandler(this));

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

但是,这似乎并不奏效。 每当任何未处理的线程抛出异常时,我都会获得库存,操作系统默认对话框(“对不起! - 应用程序已停止 - 意外对话”)。

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


这应该是你需要做的一切。 (确保你之后导致进程停止 - 事情可能处于不确定状态。)

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

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


很久以前,我发布了自定义处理Android崩溃的简单解决方案。 这是一个小黑客,但它适用于所有Android版本(包括棒棒糖)。

首先是一点理论。 在Android中使用未捕获的异常处理程序时遇到的主要问题与主要(又名UI)线程中引发的异常有关。 这是为什么。 当应用程序启动系统调用ActivityThread.main方法准备并启动应用程序的主循环器时:

public static void main(String[] args) {
  …
  …
    Looper.prepareMainLooper();
  …
    Looper.loop();
    throw new RuntimeException("Main thread loop unexpectedly exited");
}

主要looper负责处理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);
        }
    }
}

正如你所看到的,未捕获的异常处理程序仅用于在后台线程中抛出的异常。 以下处理程序捕获这些异常并将它们传播到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仓库中找到:https://github.com/idolon-github/android-crash-catcher


FWIW我知道这有点偏离主题,但我们一直在使用Crittercism的成功免费计划。 它们还提供一些高级功能,例如处理异常,以便应用程序不会崩溃。

在免费版本中,用户仍然看到崩溃,但至少我得到了电子邮件和堆栈跟踪。

我们也使用iOS版本(但我从同事那里听说它不太好)。


这里有类似的问题:

  • 全局未捕获异常处理程序 - >电子邮件日志给我?
  • 是否有可能在Android中创建某种全局异常处理程序?
  • 链接地址: http://www.djcxy.com/p/34883.html

    上一篇: Ideal way to set global uncaught exception Handler in Android

    下一篇: What is the best way in c# to determine whether the programmer is running the program via IDE or it's user?