问题描述
我曾经在 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而不改变其功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!