Using global exception handling with "setUncaughtExceptionHandler" and "Toast"
I am trying to create a simple exception handler which will help me debug the application. Right now, when I have an exception I am forced to connect with Eclipse debugger merely to see the exception details.
To avoid that I've used setUncaughtExceptionHandler to handle any unhandled exception and display a Toast on the exception. Unfortunately, that doesn't work.
public class TicTacToe extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Thread.currentThread().setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread thread, Throwable ex) {
Toast.makeText(TicTacToe.this, "TOAST", Toast.LENGTH_LONG).show();
}
});
setContentView(R.layout.main);
Button continueButton = (Button) findViewById(R.id.cell01);
continueButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
int i = 5;
i = 5 / 0;
Toast.makeText(TicTacToe.this, "BUTTON", Toast.LENGTH_LONG).show();
}
});
}
}
Essentially I made a form with a single button, pressing on which, it would throw a devision-by-zero exception. However, pressing the button doesn't cause the global toast handler to show. Instead, the button stays orange (pressed) and nothing happens.
Needless to say, if I comment out i = 5 / 0; I see the toast that says that a button was pressed.
Two questions: 1) Why isn't the toast showing in the UncaughtExceptionHandler body? How do cause it to show? 2) Is there an alternative/better way for global exception handling? I guess I could install aLogCat on the android simulator and simply log the uncaught exception, it seems, however, less comfortable - I will nee开发者_开发技巧d to be switching applications just to see exception details.
Thanks!
It is possible. You need to do it inside another thread
Then it should be like this
Thread.currentThread().setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread thread, Throwable ex) {
new Thread() {
@Override
public void run() {
Looper.prepare();
Toast.makeText(TicTacToe.this, "TOAST", toast.LENGTH_LONG).show();
Looper.loop();
}
}.start();
}
});
You're not seeing anything because the exception happened on your UI thread and the stack unrolled all the way. So there is no more Looper and there is no support there that is used to display the Toast. If you want to display the exception information on screen you'll most likely need to start another Activity in another process.
There is also a problem with your UncaughtExceptionHandler. You really should keep a reference to the old one and call it at the end of uncaughtException
this allows the system to display the Force Close button.
I know it's an old question but I hope I can save someone from frustration and wasting time.
Qberticus is right, you can't start an Activity on the same process, but you can kill the current process and have android run it in a new one:
Intent intent = new Intent(myContext, AnotherActivity.class);
intent.putExtra("error", errorReport.toString());
myContext.startActivity(intent);
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(10);
refer to this page for an awesome working example:
精彩评论