ANR定位与处理

 

ANR产生原因

UI线程响应超时就会产生ANR。具体地说,ANR可分为三个场景:

  • View的触摸事件在5s内没有得到响应;
  • BroadcastReceiver的onReceive()运行在UI线程,在10s内没有处理完;
  • Service的各个生命周期运行在UI线程,在20s内没有处理完。

ANR代码定位

可以通过分析data/anr/traces.txt文件得到相关信息。

BlockCanary检测ANR

原理

获取UI线程的Looper,调用Looper.setMessageLogging(实现了Printer接口的对象),即可使UI线程在每次dispatchMessage()后调用Printer接口的println()。于是在println()中记录每次调用时间,与上次调用时间比较,如果时间差超过卡顿阈,就判断为卡顿,输出Log信息并给出提示。

使用

debug引入

debugCompile 'com.github.markzhai:blockcanary-android:xxx'

在应用的Application子类的onCreate()中完成初始化

BlockCanary.install(this, new AppContext()).start();

其中AppContext是BlockCanaryContext的子类,需重写几个抽象方法

@Override
public String provideQualifier() {
	return 输出信息;
}
 
@Override
public int provideBlockThreshold() {
	return 卡顿阈;
}
 
@Override
public boolean displayNotification() {
	return 卡顿时是否显示Notification;
}
 
@Override
public boolean stopWhenDebugging() {
	return false;
}