defaultExceptionHandler

defaultExceptionHandler

我在Stackoverflow上问了this问题,答案对我有用,它覆盖了handleUncaughtException,我保存了异常并抛出了默认的Unfortunately app has stopped working,但是当我将其集成到我的应用程序中时,我遇到了一个问题。

这就是我得到的答案。

private Thread.UncaughtExceptionHandler defaultExceptionHandler;

    public void registerCrash(){
        defaultExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();

        Thread.setDefaultUncaughtExceptionHandler (new Thread.UncaughtExceptionHandler(){
            @Override
            public void uncaughtException (Thread thread, Throwable e){
                handleUncaughtException (thread, e);
                if(defaultExceptionHandler != null){
                    defaultExceptionHandler.uncaughtException(thread, e);
                }
            }
        });
    }

它的作用是,首先转到handleUncaughtException (thread, e);,我以这种方法保存崩溃日志,然后读取此行
 if(defaultExceptionHandler != null){
    defaultExceptionHandler.uncaughtException(thread, e);
}

在这里,我们再次抛出未捕获的异常,因此它再次进入第一行,并再次保存该异常,并且此循环进入循环,并且应用程序变得无响应。

我想要的是保存崩溃日志,然后向用户显示默认的Unfortunate消息。

编辑

在应用程序启动时,它显示为:
defaultExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();

当应用程序崩溃时,它会读取这些行
Thread.setDefaultUncaughtExceptionHandler (new Thread.UncaughtExceptionHandler(){
    @Override
    public void uncaughtException (Thread thread, Throwable e){

        handleUncaughtException (thread, e); //Custom Method

        if(defaultExceptionHandler != null){
            defaultExceptionHandler.uncaughtException(thread, e);
        }
    }

因此,首先转到我提供了自定义实现的handleUncaughtException(),然后转到此;
if(defaultExceptionHandler != null){
  defaultExceptionHandler.uncaughtException(thread, e);
}
defaultExceptionHandler永远不会为空;因此,在发生多次崩溃的情况下,它会循环运行。

我曾尝试在其中添加count,但每次都添加0

最佳答案

最可能的解释是您的registerCrash()方法被调用了两次。

第一次,您注册Handler 1;目前没有默认处理程序,因此它将defaultExceptionHandler设置为null。第二次,您注册Handler 2,然后更新defaultExceptionHandler以指向Handler 1

在未捕获的异常上,首先调用Handler 2。它调用您的自定义处理程序方法,然后调用defaultExceptionHandler,现在指向Handler 1
Handler 1被调用。它第二次调用您的自定义处理程序方法,然后调用defaultExceptionHandler,它现在指向自身。重复此步骤,直到堆栈溢出为止。

我建议进行两项更改。首先,添加一个保护措施以确保您只注册一次崩溃处理程序。其次,不要将回退处理程序存储在字段中;将其捕获在一个闭包中,这样您的处理程序看到的值就不会改变。

private static final AtomicBoolean CRASH_HANDLER_REGISTERED = new AtomicBoolean();

public void registerCrash() {
    if (CRASH_HANDLER_REGISTERED.compareAndSet(false, true)) {
        final Thread.UncaughtExceptionHandler defaultHandler =
            Thread.getDefaultUncaughtExceptionHandler();

        Thread.setDefaultUncaughtExceptionHandler(
            new Thread.UncaughtExceptionHandler() {
                @Override
                public void uncaughtException(Thread thread, Throwable e) {
                    handleUncaughtException(thread, e); // Custom Method

                    if (defaultHandler != null) {
                        defaultHandler.uncaughtException(thread, e);
                    }
                }
            }
        );
    }
}

关于android - 如何在不更改其功能的情况下覆盖句柄UncaughtException,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45402231/

10-11 00:44