如何覆盖handleUncaughtException而不改变其功能 [英] How to override handleUncaughtException without changing its functionallity

查看:1169
本文介绍了如何覆盖handleUncaughtException而不改变其功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我曾经在 Stackoverflow 中回覆这个问题,答案适用于我,它覆盖了 handleUncaughtException ,我保存异常并抛出默认的不幸的是,应用程序已停止工作 ,但是当我将其整合到我的应用程序中时,我面临着一个问题。



这是我得到的答案。

  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(线程,e); 我保存崩溃日志在这个方法,然后它读这行

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

这里我们再次抛出未捕获的异常,所以再次进入第一行,并再次保存异常,并且循环,并且应用程序变得没有响应。



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



编辑



在应用程序启动时,它读取此;

  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()那里我提供了自定义的实现,然后它到这里;

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

defaultExceptionHandler 永远不会为空;所以在多次崩溃的情况下进行循环。



我尝试添加 count 那里,但每次都是 0

解决方案

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



第一次,您注册 Handler 1 ;在这一点上没有默认处理程序,所以它将 defaultExceptionHandler 设置为 null 。第二次,您注册 Handler 2 ,然后更新 defaultExceptionHandler 指向处理程序1



在未捕获的异常情况下,首先调用 Handler 2 。它调用您的自定义处理方法,然后调用 defaultExceptionHandler ,现在指向 Handler 1



处理程序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线程,e); //自定义方法

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


I asked this question some time back on Stackoverflow, the answer worked for me, It overrides thehandleUncaughtException, I save the exception and throws the default Unfortunately app has stopped working, but when i integrated this in my app, I am facing an issue.

This is the answer i got.

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);
                }
            }
        });
    } 

What it does, first it goes to handleUncaughtException (thread, e); i save the crash log in this method, then it reads this line

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

here we throw uncaught exception again, so it goes to the first line again, and again saves the exception, and this goes in loop, and application becomes not responding.

What i want is to save crash log, and then show the default Unfortunate message to user.

EDIT

On Application launch it reads this;

defaultExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();

When application crashes, it reads these lines

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);
        }
    }

So it first goes to handleUncaughtException() there i have provided custom implementation, then it goes to this;

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

The defaultExceptionHandler is never null; So it goes in a loop in case of multiple crashes.

I have tried adding count there, but it was 0 each time.

解决方案

The most likely explanation is that your registerCrash() method is being called twice.

The first time, you register Handler 1; there is no default handler at this point, so it sets defaultExceptionHandler to null. The second time, you register Handler 2, and then update defaultExceptionHandler to point to Handler 1.

On an uncaught exception, Handler 2 gets invoked first. It calls your custom handler method, then invokes defaultExceptionHandler, which now points to Handler 1.

Handler 1 gets invoked. It calls your custom handler method a second time, then it invokes defaultExceptionHandler, which now points to itself. This step repeats until your stack overflows.

I suggest two changes. First, add a guard to ensure you only register your crash handler once. Second, don't store the fallback handler in a field; capture it in a closure so the value seen by your handler never changes.

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);
                    }
                }
            }
        );
    }
}

这篇关于如何覆盖handleUncaughtException而不改变其功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆