我们先来看下以下几种异常处理情景

没有任何异常处理
触发异常代码后,应用直接崩溃

为线程设置了默认的异常处理器
触发异常代码后,代码中止执行,执行异常处理器的逻辑,应用不会崩溃

为线程设置了默认的异常处理器,但是主线程在setContentView之前,或者界面尚未加载完毕时发生异常
默认的异常处理器虽然阻止了应用崩溃,但是创建界面的代码却因为异常而中止了,由于界面没有加载出来,应用又未崩溃,我们看到的便是一直黑屏的情景

为线程设置了默认的异常处理器,但是handler在处理消息时发生了异常
默认的异常处理器虽然阻止了应用崩溃,但是消息队列却因为异常而中止了轮询处理,而安卓整个应用是基于消息机制的,无法再继续处理其它工作,便出现了应用一直无响应但又不崩溃的情况

通过以上分析,想必大家已经猜到黑屏和卡死的原因了
这是由于我们处理异常的方式不对造成的,正确的做法应该是

如果setContentView之前的代码,或者handler处理消息的代码,可能发生异常,要手动为这些代码单独添加异常处理
默认的异常处理器是为整个线程添加的,虽然可以捕获异常防止崩溃,但是线程也结束工作了,而消息队列实质也就是一个线程在轮询任务而已,一旦停止工作,其它任务也都无法工作了

我们可以通过以下代码来模拟DefaultExceptionHandler和消息队列的的工作逻辑

new Thread(()->{
	    try{
	        while (true){
	        	//只要一个消息发生异常,就会跳入异常处理器,整个消息队列都将停止工作
	            MessageRunnable runnable = looper.getMessageQueue().obtainMessage();
	            handler.handleMessage(runnable);
	        }
	    }catch (Exception e){
	        exceptionHandler.onException(e);
	    }
	}).start();