前言
最近上的一个版本中,突然bugly
的Java异常一个都没有了,正好升级了bugly的版本,还以为接入有问题,排查一些正常,特自信的说版本代码优秀…0 bug~~~
可是后面细想几百万的DAU,一个Java异常都没有都没有,这太不正常了。
目前项目中捕获全局异常的有:bugly、umeng、自己。
排查
bugly的捕获异常代码实现
文件路径:com.tencent.bugly.crashreport.crash.a
保存之前的UncaughtExceptionHandler
,将自己设置为默认异常处理器Thread.setDefaultUncaughtExceptionHandler(this)
对捕获异常做分发
umeng的捕获异常代码实现
文件路径:com.umeng.analytics.pro.l
实现逻辑和bugly类似
自己的捕获异常代码实现
问题定位:handleException
笔误写错了!
处理,导致之前默认异常处理未被调用,而且自己异常捕获写在最后,覆盖了之前的异常捕获
建议
为了避免此种问题再次发生,对异常捕获可以参考以下代码进行扩展
public class CrashHandler implements Thread.UncaughtExceptionHandler {
private final Thread.UncaughtExceptionHandler mDefaultHandler;
public CrashHandler() {
//缓存之前的默认异常捕获
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(this);
}
@Override
public void uncaughtException(Thread t, Throwable e) {
//分发异常
if (mDefaultHandler != null) {
mDefaultHandler.uncaughtException(t, e);
}
//TODO 自己处理
Log.w("CrashHandler", e);
}
}
当然最简单的方式是将自己的UncaughtExceptionHandler
写在bugly
和umeng
的前面,让bugly
和umeng
分发异常给自己,但是你也不能保证你前面就没有其他的异常捕获监听,所以还是建议用上述方法。
扩展
- Java中并不是所有的异常都会提示
try-catch
进行捕获的,比如RuntimeException
- 线程是独立执行的代码片断,线程的问题应该由线程自己来解决,而不要委托到外部。
setUncaughtExceptionHandler
- 对象方法
- 用于指定Thread的异常捕获
- 如未指定会去取ThreadPool中的异常捕获
- 只能捕获
executorService.execute
执行的异常 - 不能捕获
executorService.submit(runnable)
,上述异常通过catch (ExecutionException e)
进行捕获
setDefaultUncaughtExceptionHandler
- 类方法
- 用于捕获所有Thread中的异常捕获
- 如Thread指定了异常捕获,则不调用默认的