Crash app in Thread.setDefaultUncaughtExceptionHan

2019-04-14 10:30发布

问题:

I would like to crash my app on purpose after logging my own error. The Handler is registered in Application.onCreate():

// set global exception handler
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread thread, final Throwable ex) {
  // unregister
  Thread.setDefaultUncaughtExceptionHandler(null);

  // do report ...

  // crash app -does not work, app is frozen
  if (ex instanceof RuntimeException)
    throw (RuntimeException) ex;
  throw new RuntimeException("Re-throw", ex);
}

However, my app freezes instead of crashing with a dialog. How can I crash the application as it would if I hadn't registered the handler?

回答1:

This bit of code is never going to work.

An uncaught exception handler is called after a thread has terminated due to an exception that was not caught. If you then attempt to re-throw the exception, there will be nothing else to catch it.

  • If you want to have your re-thrown exception handled in the normal, you have to do the logging further up the stack.

  • The only other option you have is to explicitly chain to another UncaughtExceptionHandler.


I suspect that the freeze is you are experiencing is a direct consequence of the current thread dying.


FOLLOWUP:

... is there some other way in Android to intercept exceptions at a global level, without using Thread.setDefaultUncaughtExceptionHandler?

AFAIK, no.

Or how would the chaining look like?

Something like this:

public void uncaughtException(Thread thread, final Throwable ex) {
    // do report ...

    getSomeOtherHandler(...).uncaughtException(thread, ex);
}

Or, since ThreadGroup implements UncaughtExceptionHandler, ...

public void uncaughtException(Thread thread, final Throwable ex) {
    // do report ...

    thread.getThreadGoup().uncaughtException(thread, ex);
}

Basically, you just call some other handler. It's not rocket science.

But note that you can't catch and recover from an exception in the "normal" way once you've landed in one of these handlers.