android - 替换默认的未捕获异常处理程序以避免崩溃对话框

标签 android

我们想替换默认的未捕获异常,以便不显示默认的崩溃对话框。

问题 是如果您调用 Thread.setDefaultUncaughtExceptionHandler(YourHandler) 然后在出现异常的情况下应用程序“卡住”并且您会收到 ANR(应用程序未响应)对话框。我们对 System.exit()Process.killProcess() 进行了实验,它们解决了这个问题,但从对此事的阅读来看,似乎不鼓励这样做。

那么如何才能正确完成呢?

最佳答案

长话短说

com.android.internal.os.RuntimeInit.UncaughtHandler中采用默认未捕获异常处理程序的框架实现中的代码省略显示对话框的部分。

深入分析

首先很明显 System.exit()Process.killProcess() 在应用程序崩溃的情况下是强制性的(至少人们是这样的在谷歌认为)。
重要的是要注意 com.android.internal.os.RuntimeInit.UncaughtHandler 可能(并且确实)在框架版本之间发生变化,而且其中的一些代码不适用于您自己的实现。
如果您不关心默认的崩溃对话框并且只想向默认处理程序添加一些内容,您应该包装默认处理程序。 (例如见底部)

我们默认的未捕获异常处理程序(无对话框)

Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable ex) {
    try {
        // Don't re-enter -- avoid infinite loops if crash-reporting crashes.
        if (mCrashing) {
            return;
        }
        mCrashing = true;

        String message = "FATAL EXCEPTION: " + t.getName() + "\n" + "PID: " + Process.myPid();
        Log.e(TAG, message, ex);
    } catch (Throwable t2) {
        if (t2 instanceof DeadObjectException) {
            // System process is dead; ignore
        }
        else {
            try {
                Log.e(TAG, "Error reporting crash", t2);
            } catch (Throwable t3) {
                // Even Log.e() fails!  Oh well.
            }
        }
    } finally {
        // Try everything to make sure this process goes away.
        Process.killProcess(Process.myPid());
        System.exit(10);
    }
}

})

包装默认处理程序

final Thread.UncaughtExceptionHandler defHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
    @Override
    public void uncaughtException(Thread t, Throwable ex) {
        try {
            //your own addition 
        } 
        finally {
            defHandler.uncaughtException(t, ex);
        }
    }
});

关于android - 替换默认的未捕获异常处理程序以避免崩溃对话框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46070393/

相关文章:

android - 在 Oreo 中注册静态广播接收器

android - 在 viewPager 中的 fragment 之间滑动时,选项卡高光不会改变

android - 我们可以使用android :attr/spinnerStyle for TextView in Android吗

android - 局部委托(delegate)属性和内联属性不支持扩充赋值和增量

android - 尝试在设备 mako 的模拟器上启动 android 时出现错误 'ko:Invalid cache partition image type: yaffs2 (expected ext4)'?

android - Android 中的缓冲图像

android - 使用 View.GenerateViewId 创建 ID 时如何查找带 ID 的 TextView

android - 如何覆盖 Google Play 服务的权限要求?

java - SnappyDB 的默认值

Android - 仪表测试期间应用程序的模拟方法