我正在尝试创建一个简单的异常处理程序,它将帮助我调试应用程序。现在,当我遇到异常时,我被迫连接Eclipse调试器只是为了查看异常细节。
为了避免我使用 setUncaughtExceptionHandler 来处理任何未处理的异常并在异常上显示Toast。不幸的是,这不起作用。
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();
}
});
}
}
基本上我用一个按钮做了一个表单,按下它,它会抛出一个零切换异常。但是,按下按钮不会导致显示全局Toast处理程序。相反,按钮保持橙色(按下),没有任何反应。
毋庸置疑,如果我注释掉 i = 5/0; ,我会看到一个按钮,表示已按下按钮。
两个问题: 1)为什么吐司没有出现在 UncaughtExceptionHandler 主体中?怎么导致它显示? 2)是否有替代/更好的全局异常处理方式?我想我可以在android模拟器上安装aLogCat并简单地记录未捕获的异常,但似乎不太舒服 - 我需要切换应用程序只是为了查看异常细节。
谢谢!
答案 0 :(得分:14)
有可能。你需要在另一个线程中做到这一点 那应该是这样的
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();
}
});
答案 1 :(得分:11)
您没有看到任何内容,因为您的UI线程上发生了异常,并且堆栈一直展开。所以没有更多的Looper,并且没有用于显示Toast的支持。如果要在屏幕上显示异常信息,则很可能需要在另一个进程中启动另一个Activity。
您的UncaughtExceptionHandler也存在问题。你真的应该保留对旧的引用并在uncaughtException
结束时调用它,这允许系统显示强制关闭按钮。
答案 2 :(得分:1)
我知道这是一个老问题,但我希望我可以拯救某人免于沮丧和浪费时间。
Qberticus是对的,你不能在同一个进程上启动一个Activity,但是你可以杀死当前的进程并让android以新的方式运行它:
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);
请参阅this page了解一个非常棒的工作示例: