问题
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.
回答1:
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);
}
}
}
);
}
}
回答2:
I suggest you to try another approach, avoid overriding exceptions, catch it and retrive the error code, and do this:
when x code with x conditions verify, do that
来源:https://stackoverflow.com/questions/45402231/how-to-override-handleuncaughtexception-without-changing-its-functionallity