Catch all possible android exception globally and

2019-01-22 23:24发布

问题:

I know the best way to prevent system crashes is catching all possible exception in different methods. So I use try catch blocks every where in my code. However as you know sometimes you forget to test some scenarios which cause some unhanded exceptions and a user gets "Unfortunately App stopped working..." message. This is bad for any application. Unfortunately the people who will use my app are not native English, so they will not understand crash message too.

So I want to know is it possible to catch all possible exception globally ( with just one try catch block in some main classes not all classes and methods!!!) and reload application automatically and without any weird messages? Or at least is it possible to change the crash message?

Thanks.

回答1:

In your onCreate

Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
            @Override
            public void uncaughtException(Thread paramThread, Throwable paramThrowable) {
                //Catch your exception
                // Without System.exit() this will not work.
                System.exit(2);
            }
        });


回答2:

So I want to know is it possible to catch all possible exception globally ... and reload application automatically

DO NOT DO THIS. If your app enters a state where even just launching it causes a crash, you will create an endless loop of crashing and relaunching that the user cannot get out of.

The error message is not weird; it is the system message, and it is translated in all supported languages on the device.

The only thing you should be doing is using some kind of crash reporting library to report crashes back to you without the user having to do anything, so that you can fix your app and submit an update. You can set a custom UncaughtExceptionHandler in your Application's onCreate(), but I would limit this to logging data and perhaps preparing to send that to you for debugging purposes, and then forward the call back to the default UncaughtExceptionHandler. This is exactly what a crash reporting library does.

I know the best way to prevent system crashes is catching all possible exception in different methods. So I use try catch blocks every where in my code.

No, the best way to to write good code and fix bugs before releasing. It is considered bad practice to catch all forms of exceptions indiscriminately. You should be using try-catch blocks only where either

  1. A method call can throw a checked exception, in which case the compiler forces you to surround with try-catch or rethrow the exception; or
  2. You want to handle certain unchecked (runtime) exceptions. An example would be parsing user input with something like Integer.parseInt(), catching the NumberFormatException and showing message to the user that their input is invalid.

However as you know sometimes you forget to test some scenarios

Then improve your coding and your testing practices. Do not use this as an excuse for taking rash actions.

Unfortunately the people who will use my app are not native English, so they will not understand crash message too.

Which crash message? If you mean the system's crash message, that should be in whatever language they set their device to. If you mean your crashmessage (e.g. in logcat), they shouldn't have to. They should send you the crash message, you should fix the app and distribute an update. Don't expect an end user to do any legwork in determining what causes your app to crash. Better to use some kind of crash reporting library.



回答3:

There you go:

    Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
    @Override
    public void uncaughtException(Thread paramThread, Throwable paramThrowable) {

        new Thread() {
            @Override
            public void run() {
                Looper.prepare();
                Toast.makeText(getActivity(),"Your message", Toast.LENGTH_LONG).show();
                Looper.loop();
            }
        }.start();
        try
        {
            Thread.sleep(4000); // Let the Toast display before app will get shutdown
        }
        catch (InterruptedException e) {    }
        System.exit(2);
    }
});