理想的方式设置在Android的全球未捕获的异常处理程序理想的方式设置在Android的全球未捕获的

2019-05-10 10:46发布

我想成立一​​个全球性的未捕获的异常处理程序在我的Android应用程序的所有线程。 所以,在我的Application子类我设置的一个实现Thread.UncaughtExceptionHandler为捕获的异常默认处理程序。

Thread.setDefaultUncaughtExceptionHandler(
                new DefaultExceptionHandler(this));

在我的实现,我想显示AlertDialog显示相应的异常信息。

然而,这似乎并没有工作。 无论何时,一个异常被抛出肚里未办理任何线索,我得到的股票,OS-默认对话框(“对不起! - 应用 - 已-停意外对话框”)。

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

Answer 1:

这应该是所有你需要做的。 (请确保您导致进程之后停止 - 东西可能是在一个不确定的状态。)

要检查的第一件事是是否Android的处理还是会被调用。 这有可能是你的版本是被称为但是致命的失败和system_server显示了当它看到进程崩溃的通用对话框。

在你的处理器的顶部添加一些日志消息,看看它到达那里。 打印从getDefaultUncaughtExceptionHandler结果,然后抛出一个未捕获的异常导致崩溃。 保持对logcat的输出眼看到发生了什么事情。



Answer 2:

我张贴的简单的解决方案为客户定制的Android的崩溃,一个很久以前。 这是一个有点哈克但它适用于所有Android版本(包括棒棒堂)。

第一种理论的一点点。 当你在Android上使用未捕获的异常处理程序中的主要问题都与主(又名UI)线程抛出的异常。 这里是为什么。 当应用程序启动系统调用ActivityThread.main方法,准备并起动主尺蠖您的应用程序:

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听者):

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



Answer 3:

FWIW我知道这是稍微偏离主题,但我们一直在使用Crittercism的免费计划成功。 他们还提供了一些高级功能,如处理异常,因此应用程序不会崩溃。

在免费版本中,用户仍然可以看到飞机坠毁,但至少我得到的电子邮件和堆栈跟踪。

我们还使用了iOS版本(但我从我的同事们听说,这是不太好)。


这里有类似的问题:

  • 全球未捕获的异常处理程序- >电子邮件日志给我?
  • 是否有可能建立某种形式的全球Android的异常处理的?


Answer 4:

我想禁用,在您的uncaughtException()方法不调用其中previousHandler被设置previousHandler.uncaughtException()

previousHandler = Thread.getDefaultUncaughtExceptionHandler();


Answer 5:

它不工作,直到你打电话

android.os.Process.killProcess(android.os.Process.myPid());

在你的UncaughtExceptionHandler的尽头。



文章来源: Ideal way to set global uncaught exception Handler in Android