Android客户端异常检测
16lz
2021-01-26
一、崩溃检测原理
通过thread.setDefaultUncaughtExceptionHandler(),设置默认异常处理Handler,对未被捕获异常进行处理。
虚拟机会将没有处理的异常交给默认的UncaughtExceptionHandler处理,我们需要做的是将异常上报至服务端处理,APP端按照原本的逻辑走下去。
代码很简单:
/*** 系统默认的handler*/Thread.UncaughtExceptionHandler mDefaultHandler;mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { @Override public void uncaughtException(Thread t, Throwable e) { handleException(thread, ex); //收集数据上报之后交给默认的handler处理 if (mDefaultHandler != null) { mDefaultHandler.uncaughtException(thread, ex); } }});
我们在handleException中手机设备的硬件和软件信息将其上报给服务端。
二、ANR检测
方法一:通过向UI线程发送消息判断
Android UI线程是一个通过Looper进行消息循环的过程,UI线程不断的从消息队列中获取消息进行处理,而UI线程不会处理耗时任务,所以向UI线程发送的消息会得到及时处理,如果超过一段时间没有被处理,那说明发生了ANR。
所以实现方案是:
开一个子线程,定时想UI线程发送消息。若没有及时处理,说明主线程没有响应,认为是ANR异常。
@Override public void run() { while (true) { watchDogHandler.sendEmptyMessage(MESSAGE_WATCHDOG_TIME_TICK); try { Thread.sleep(ACTIVITY_ANR_TIMEOUT); } catch (InterruptedException e) { e.printStackTrace(); } //如果相等,说明过了ACTIVITY_ANR_TIMEOUT的时间后watchDogHandler仍没有处理消息,已经ANR了 if (timeTick == lastTimeTick) { //todo 上报ANR异常 } else { lastTimeTick = timeTick; } } } private class WatchDogHandler extends Handler { @Override public void handleMessage(Message msg) { timeTick++; timeTick = timeTick % Integer.MAX_VALUE; LogUtil.i("timeTick = " + timeTick); LogUtil.i("lastTimeTick = " + lastTimeTick); } }
方法二:通过监控主线程处理消息的时长判断
通过查看Looper源码知道,里面有一段很关键的代码如下:
public static void loop() { ... for (;;) { ... if (logging != null) { logging.println(">>>>> Dispatching to " + msg.target + " " + msg.callback + ": " + msg.what); } ... msg.target.dispatchMessage(msg); ... if (logging != null) { logging.println("<<<<< Finished to " + msg.target + " " + msg.callback); } ... } ... } }
从上面这段代码可以看出,loop方法在处理每一个消息前后都会打印相关的日志,那么我们可以设置自定义的logging来判断每次处理消息的耗时。
Looper.getMainLooper().setMessageLogging(new Printer() { @Override public void println(String x) { //通过计算两次打印日志的时间来判断处理消息的时间是否过长,从而认为是ANR。 }});
更多相关文章
- SpringBoot 2.0 中 HikariCP 数据库连接池原理解析
- Android(安卓)中handler 的应用
- Android应用程序键盘(Keyboard)消息处理机制分析(三)
- Android:Android基础知识
- android有了eventbus,一切与关界面通信问题迎刃而解。
- Android中Handler消息处理
- Android(安卓)四种异步操作UI界面的方法
- Android在非UI线程中更新UI的方法
- 【移动开发】Android游戏开发SurfaceView应用----手指发动小球(小