ANR异常相信做Android开发的都知道是什么原因一起的,下面来说下如何监控App是否发生。
1. 有个开源的项目BlockCanary,开发者说是用来监控ANR的,不过有个缺点就是它是通过在主线程监控Android生命周期方法执行时间的,即如果方法的执行时间大于阀值,则认为发生了ANR,这种不太准确,因为不同手机系统的ANR时间不一致,阀值的设定不好掌握,而且一旦发生了ANR,监控方法就无法收到方法结束时间,无法监控到。
代码就不贴了,在github搜索即可。
2. 还有另外一个开源项目
核心代码如下:
private final Runnable _ticker = new Runnable() {
@Override public void run() {
_tick = (_tick + 1) % Integer.MAX_VALUE;
}
};
@Override
public void run() {
int lastTick;
int lastIgnored = -1;
while (!isInterrupted()) {
lastTick = _tick;
_uiHandler.post(_ticker);
try {
Thread.sleep(_timeoutInterval);
}
catch (InterruptedException e) {
_interruptionListener.onInterrupted(e);
return ;
}
// If the main thread has not handled _ticker, it is blocked. ANR.
if (_tick == lastTick) {
ANRError error;
if (_namePrefix != null)
error = ANRError.New(_namePrefix, _logThreadsWithoutStackTrace);
else
error = ANRError.NewMainOnly();
_anrListener.onAppNotResponding(error);
return;
}
}
}
也有一个缺点就是,它也需要设置个阀值_timeoutInterval,即在这个阀值内,如果主线程还没有处理完,则认为发生了ANR;或者,主线程已经发生ANR了,但还要等阀值后才能记录该ANR。
github地址:外链网址已屏蔽
核心原理是使用了主线程的Handler Looper机制。
具体可以参考 外链网址已屏蔽