Toast not showing up in UnCaughtExceptionHandler

橙三吉。 提交于 2019-12-05 20:58:08

问题


I am using this code to handle any uncaught exceptions which might cause my application to crash.

public class ExceptionHandler implements java.lang.Thread.UncaughtExceptionHandler {
    private final Context myContext;

    public ExceptionHandler(Context context) {

        myContext = context;
    }

    public void uncaughtException(Thread thread, Throwable exception) {

        Toast.makeText(myContext,
                "The application has crashed, and a report is sent to the admin",
                Toast.LENGTH_SHORT).show();
        StringWriter stackTrace = new StringWriter();
        exception.printStackTrace(new PrintWriter(stackTrace));
        System.err.println(stackTrace);// You can use LogCat too
        Intent intent = new Intent(myContext, CrashActivity.class);
        myContext.startActivity(intent);
        Process.killProcess(Process.myPid());
        System.exit(10);
    }
}

When i run it with a known but uncaught exception(just to test), activity "CrashActivity" is called but the Toast which must come before it is not showing up.

Actually i wanted to show only Toast and then call myContext.finish(); instead of going to the CrashActivity. But that toast in not visible.

Where am i wrong?


回答1:


You are probably calling the Toast from a thread while a toast should be called from the UI thread...

If this isn't helping, please provide us the logcat output so we can see what kind of error you are getting.




回答2:


Found this question while googling for exact the same problem. As far as I can tell it is not necessary to have the Toast.show() called from the UI thread as long as there is an Application context.

AFAIK: The problem that here occurs is the following: You're trying to show a Toast and immediately afterwards your application is shut down by the VM, which means your Toast is shutdown as well.

A solution for the problem is the following:

  • Run the Toast from a sepearate Thread
  • Delay shutdown of your application in the Uncaught Exception Handler.

What I do is the following:

In Application::onCreate():

Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
    @Override
    public void uncaughtException(Thread thread, Throwable ex)
    {
        new Thread() {
            @Override
            public void run() {
                Looper.prepare();
                Toast.makeText(getApplicationContext(), "Application crashed", Toast.LENGTH_LONG).show();
                Looper.loop();
            }
        }.start();

        try
        {
            Thread.sleep(4000); // Let the Toast display before app will get shutdown
        }
        catch (InterruptedException e)
        {
            // Ignored.
        }
    }
});

It is similiar to how the Toast notification in ACRA works (in fact this is where I got the hint from).




回答3:


Calling System.exit(0) from within Android UncaughtExceptionHandler helps application recover from error and relaunch last Activity. IMHO, user experience gets improved significantly. However, this approach needs to be tried and tested on multiple android platforms. Have tried this on GB and JB. It worked fine. Additionally, I heard from others (I am new to Android) that invoking System.exit() is not recommended in Android but ..could use this as a nice recovery option for android application crashes.

    public void uncaughtException(Thread thread, Throwable ex) {
        new Thread() {
            @Override
            public void run() {
                Looper.prepare();  
                Toast.makeText(YourActivity.this, "Application has Crashed. Recovering now.", Toast.LENGTH_LONG).show();
                /* Log relevant message/analytics from here. */
                System.exit(1);
                Looper.loop();
            }
        }.start();
    }


来源:https://stackoverflow.com/questions/11609640/toast-not-showing-up-in-uncaughtexceptionhandler

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!