前言
一个引发讨论的楔子,以下三种现象有什么区别:
- App停止运行
- App暂无响应
- App闪退
答案:
产生原因不同: - 停止运行是UNCheckException+Error
- 暂无响应是ANRDialog
- 闪退是CheckException+Error
本文讨论的主题是ANR的定义、分类、复现、分析、优化。
ANR定义
Application Not Responding
ANR类型
Input dispatching timed out
按键或触摸事件在特定时间内无响应(origin:5s)
KEY_DISPATCHING_TIMEOUT = 8*1000
12-08 10:51:08.136 763-787/system_process E/ANRManager: ANR in com.xx
(com.xx/com.xxactivity.ScreenSaverPicSelectActivity),
time=26867631
Reason: Input dispatching timed out (Waiting to send non-key event because the touched window has not finished processing certain input events that were delivered to it over 500.0ms ago. Wait queue length: 36. Wait queue head age: 8510.1ms.)
Broadcast Timeout
BroadcastReceiver在特定时间内无法处理完成
BROADCAST_FG_TIMEOUT: 10s
BROADCAST_BG_TIMEOUT: 60s
按键和广播事件时间内未响应,时间限定定义在ActivityManagerService.java类中
Service Timeout
Service在特定的时间内无法处理完成,属于小概率类型
service时间内未响应时间限定在ActiveServices.java类中
SERVICE_TIMEOUT = 20*1000;
Activity Timeout
名称 时间
Activity#onPause 500ms
Activity#onStop 10s
Activity#onDestory 10s
12-08 17:22:11.296 719-743/system_process W/ActivityManager:
Activity stop timeout for ActivityRecord{2fd135ba u0 com.xx./com.unilife.fridge.home.banner.OpenFullScreenActivity t206}
ANR原因
- 应用进程有一个主线程(main thread)和一个信息队列(main message queue) main thead == activity thread
- 主线程负责处理像Draw、Listen、receive等UI事件
- 主线程负责从消息队列中取出信息并分发它
- 主线程在完成当前信息处理之前,不会再取信息队列中的信息
- 如果主线程在处理当前信息时卡住,没有及时分发,ANR就会出现
ANR检测
ANR检测工具