使用“setUncaughtExceptionHandler”和“Toast”进行全局异常处理

时间:2010-07-03 11:49:15

标签: java android exception exception-handling

我正在尝试创建一个简单的异常处理程序,它将帮助我调试应用程序。现在,当我遇到异常时,我被迫连接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并简单地记录未捕获的异常,但似乎不太舒服 - 我需要切换应用程序只是为了查看异常细节。

谢谢!

3 个答案:

答案 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了解一个非常棒的工作示例: