ANR产生原因:
- 只有当应用程序的UI线程响应超时才会引起ANR,超时原因:
- 当前事件没有机会得到处理
- 当前的事件正在处理,但是由于耗时太长没能及时完成
- 引发ANR的原因;
- View的按键事件或者触摸事件在5s内无法得到响应
- BroadcastReceiver的onReceive()函数在10s内没有得到处理
- Service各个生米周期函数在20s内没有得到处理
典型的ANR场景分析:
- 应用程序UI线程存在耗时任务,例如在UI线程中进行网络请求(Android4.0之前,4.0之后会报错),数据库操作或者文件操作等,可能会导致UI线程无法及时处理用户的输入。
- UI线程等待子线程释放某个锁,从而用户无法输入
- 耗动画可能需要大量的计算工作,可能导致CPU负载过重
ANR的避免和检测:
StrictMode: 是AndroidSDk提供的一个用来检测代码中是否存在违规操作的工具类,它主要检测两大类问题:
- 线程策略ThreadPolicy
- detectCustomSlowCalls:检测自定义耗时操作
- detectDiskReads:检测是否存在磁盘读取操作
- detectDiskWrites:检测是否存在磁盘写入操作
- detectNetwork:检测是否存在网络操作
- 虚拟机策略VmPolicy
- detectActivityLeaks:检测是否存在Activity泄漏
- detectLeakedClosableObjects:检测是否存在未关闭的Closable对象泄漏
- detectLeakedSqlLiteObjects:检测是否存在Sqlite的对象泄漏
- setClassInstanceLimit:检测类实例个数是否超过限制
- StrictMode的使用: 在应用初始化的地方Application或者MainActivity类的onCreate方法中执行:
BlockCanary:是一个非侵入式的性能监控函数库,用法和LeakCanary类似,BlockCanary主要用来监控应用主线程的卡顿,基本原理就是利用主线程的消息队列处理机制,通过对比消息分发开始和结束的时间点来判断是否超过设定的时间,如果是,则判断主线程卡顿,下面是使用的方法
- 首先在app下的build.gradle中的dependencies中添加如下代码:
- 在Application中: