Use UncaughtExceptionHandler to do what Android usually does plus extra functionality I need

946 views Asked by At

I am working on an Android library where I need to perform some action if an uncaught exception is seen.

I am successfully setting my uncaught exception handler and running the code I need, which is to post some information to a web server, but after my part is finished I want the app to then do what Android usually does, i.e. display a dialogue to the informing them that it has crashed and then exit the app, and post the details to the Google Play Developer Console.

At the moment, my uncaught exception successfully posts to the server, but then keeps the app running but in a bit of a weird state as the thread has party disappeared, where usually, if my an uncaught exception is thrown, then Android closes the app.

Below is how I am doing my uncaught exception handler:

private static void setUnhandledExceptionHandler()
    {
        Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler()
        {
            @Override
            public void uncaughtException(final Thread thread, final Throwable) {
                CrashReporter.ReportUnhandledCrash(((Exception) ex));
                Looper.loop();
            }
        });
    }

Basically, what I want to do is, have my app post to to my server via my unhandled exception handler and then quit the app, in the same way that Android usually does, i.e. display a force close error the use and close the app.

2

There are 2 answers

0
Simon Meyer On BEST ANSWER

I had a similar problem when tracking to GoogleAnalytics - most Exceptions got lost when i tried to report them in the default handler. So i cached them and reported them on the next startup.

The second trick (and this hopefully answers your question) to let the Application crash as it should is to store the 'old' DefaultUncaughtExceptionHandler and pass the exception to it.

The onCreate method below is the one of my Application class

@Override
public void onCreate()
{
     super.onCreate();
     trackCachedException();
     setupExceptionHandling();
}


private void setupExceptionHandling()
{
    _systemExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
    Thread.UncaughtExceptionHandler myHandler = new Thread.UncaughtExceptionHandler()
    {

        @Override
        public void uncaughtException(Thread thread, Throwable ex)
        {
            cacheException(thread.getName(), ex);
            if (_systemExceptionHandler != null)
            {
                _systemExceptionHandler.uncaughtException(thread, ex);
            }
        }
    };
    // Make myHandler the new default uncaught exception handler.
    Thread.setDefaultUncaughtExceptionHandler(myHandler);
}
0
Chris Cooper On

The only way I can see how you can do this is neither clean nor pleasant, so I'll say sorry before we begin...

The order of operations is:

  1. Store the uncaught exception
  2. Log the exception as you have done previously
  3. Deregister your uncaught exception handler, by calling the set method with null.
  4. Launch a new thread that throws your stored exception.

You are effectively throwing the same exception twice, but removing the recovery mechanism on the second throw.