ANR产生的原因
ANR产生的原因一眼有两种:
1.当前事件没机会处理,当前UI线程正在响应另外一个事件,当前事件由于某种原因被阻塞了;
2.当前事件正在处理,但是由于耗时太长没能及时完成。
ANR的定位和分析
当发生ANR时,我们可以打开手机内部存储的/data/anr/traces.txt进行分析和定位。
anr的避免和检测
一.StrictMode:Android SDK提供的一个用来检测代码中是否存在违规操作的工具类,主要检测两大类型的问题:
1.主线程策略
detectCustomSlowCalls:自定义耗时操作;
detectDiskReads:是否存在磁盘读操作,
detectDiskWrites:是否存在磁盘写操作,
detectNetwork:是否存在网络操作
2.虚拟机策略
detectActivityLeaks:检测是否存在activity泄漏,
detectLeakedClosableObjects:是否存在未关闭的closeable对象泄漏,
detectLeakedSqlLiteObjects:sqlite对象泄漏,
setClassInstanceLimit:检测类实例个数是否超过限制
在代码中应用Application:
@Override
protected void onCreate(Bundle savedInstanceState)
{
if (BuildConfig.DEBUG)
{
//开启线程模式
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectDiskReads()
.detectDiskWrites()
.penaltyLog()
.build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
.detectActivityLeaks()
.detectLeakedClosableObjects()
.detectLeakedSqlLiteObjects()
.penaltyLog()
.build());
}
super.onCreate(savedInstanceState);
}
二、BlockCanary:是一个非侵入式的性能监控函数库,它的用法和leakCanary类似,只不过后者监控应用的是内存泄漏,而block主要用来监控应主线程的卡顿,它的基本原理是利用主线程的消息队列处理机制,通过对比消息分支开始和结束时间来判断是否超过设定的时间,如果是。则判断为主线程卡顿。
dependencies{
compile 'om.github.markzhai:blockcanary-android:1.5.0'
// 仅在debug包启用BlockCanary进行卡顿监控和提示的话,可以这么用
debugCompile 'com.github.markzhai:blockcanary-android:1.5.0'
releaseCompile 'com.github.markzhai:blockcanary-no-op:1.5.0'
}
Application:
blockCanary.install(this,new AppBlockCanaryContext()).start();