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

时间:2017-09-06 08:32:07

标签: android

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

问题是,如果您致电Sub getArrayForGraph() Dim time As Single = 0, finalTime As Single = 0 Dim timeinterval As Decimal 'function calulates values in picoseconds Dim timeforGraph() As Long ReDim timeforGraph(TotalSample - 1) For index = 0 To TotalSample - 1 If index = 0 Then finalTime = time Else finalTime += timeinterval End If timeforGraph(index) = Math.Round(finalTime, 3) Next End Sub Sub plotGraph() Chart1.Series("series1").Points.DataBindXY(timeforGraph, bufferDMv) 'bufferAMV is array calculated from another for loop end sub ,那么如果发生异常,该应用就会冻结"然后你得到一个ANR(应用程序没有响应)对话框。我们尝试了解决问题的Thread.setDefaultUncaughtExceptionHandler(YourHandler)System.exit(),但从阅读此事看起来似乎不鼓励这样做。

那怎样才能正确完成?

1 个答案:

答案 0 :(得分:6)

TL; DR

采用框架在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);
        }
    }
});