坑一:只有一个catch。实际,一个try后面可能有若干个catch。
运行一个小项目,出现以下错误提示:
E/AndroidRuntime: FATAL EXCEPTION: Thread-2
Process: com.example.bytest, PID: 23298
由于提示信息太少,作用不大。后来发现其对应的catch代码有些小问题:
...
try {
...
} catch (IOException e) {
throw new RuntimeException(e);
}
...
问题1:其中没有打印堆栈跟踪的代码;
问题2:只catch了IOException。如果try代码块中还有其它异常,不就漏掉了吗?如果try代码块中没有输入输出异常,catch IOException不就失灵,没动静了吗?于是以上代码修改如下:
...
try {
...
} catch (IOException e) {
throw new RuntimeException(e);
} catch (RuntimeException e) {
e.printStackTrace();
}
...
加一个catch,来抓取运行时异常,其中打印了堆栈跟踪,
运行后主要提示信息如下:
W/System.err: com.obs.services.exception.ObsException: OBS servcie Error Message.
Request Error: java.net.UnknownHostException: Unable to resolve host "obs-bucket-abcd1.obs.cn-east-3.myhuaweicloud.com": No address associated with hostname
W/System.err: at com.obs.services.internal.utils.ServiceUtils.changeFromServiceException(ServiceUtils.java:529)
这就有办法下手了,好像跟网络有关系,后来经过测试发现,模拟器断网了,困扰一天的问题,很快就解决了。
坑二:IOException代替RuntimeException。实际各有各的作用
有时甚至Android Studio提醒我们要用try-cath(IOException e)"包裹"代码,也是不保险的,还要考虑是否再多一个catch来抓取其它异常。Android Studio更关心“语法”问题,对有些逻辑上的问题无能为力。
如上例代码中,try中抛出的是RuntimeException,而catch中接收的开始只有IOException,表面上看catch后面也有“××Exception e”,形式上挺像回事,实际是一个“小坑”。
坑三:catch中无堆栈跟踪。应该加上打印堆栈跟踪
catch代码块最好加上打印堆栈跟踪:
e.printStackTrace();
这样会显示出很多细节,非常有利问题分析。如同上例,未加打印堆栈跟踪时,提示很少,令人无从下手。
总结:
1、抓取异常的catch一定要考虑周全,要catch到各种可能异常。
2、特别区分好IOException与RuntimeException,尤其开始运行程序前已经断网,和程序正在运行突然断网的情况(这时可能是IOException吧)。
3、catch代码块最好加上打印堆栈跟踪:e.printStackTrace();。
4、“运行提示信息”中蓝字提示信息也很重要。
5、“是否断网”,是排查问题的有力抓手。