[Java] [ Android ] [ 异常处理 ] [ 使用Thread.setDefaultUncaughtExceptionHandler处理未捕获异常 ]

Thread.setDefaultUncaughtExceptionHandler

Thread类还有另一个方法可以处理未捕获到的异常,即静态方法setDefaultUncaughtExceptionHandler()。
这个方法在应用程序中为所有的线程对象创建了一个异常处理器。

JVM的处理

当线程抛出一个未捕获到的异常时,JVM将为异常寻找以下三种可能的处理器。
1、线程对象的未捕获异常处理器
2、线程对象所在的线程组(ThreadGroup)的未捕获异常处理器
3、默认的未捕获异常处理器
最后,如果一个处理器都没有,JVM将堆栈异常记录打印到控制台,并退出程序。(这也是你经常看到的logcat崩溃打印,AndroidRuntime抛出的打印)

最简单的代码实现

sSystemUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler(){
            @Override
            public void uncaughtException(Thread t, Throwable e) {
                //write log to file;
                sSystemUncaughtExceptionHandler.uncaughtException(thread, ex);
            }
  });

实战问题

增加下面两句测试代码,2秒在子线程制造NullPointer异常,6秒后在主线程制造NullPointer异常,
会出现如下现象:
第一次异常,正常处理,第二次主线程中的异常,一抛异常后,虚拟机立马退出,还没执行异常处理。
导致应用进程假死,界面冻结,应用无响应弹框

//在主线程中设置默认异常处理,仅写日志文件
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler(){
            @Override
            public void uncaughtException(Thread t, Throwable e) {
                //write log to file;
            }
  });

 //启动后人为制造异常,第2秒一次,第6秒一次
{
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(1000 * 2);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    String a = null;
                    Log.e(TAG, "make nullpointer exception in background thread");
                    Log.e(TAG, "len=" + a.length());
                }
            }).start();

            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    String a = null;
                    Log.e(TAG, "make nullpointer exception in main thread");
                    Log.e(TAG, "len=" + a.length());
                }
            }, 6 * 1000);
}

虚拟机因第二次主线程异常而退出

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值