摘要:ANR(Application Not Responding):应用程序没有响应,是Android应用开发及使用中相对比较常见的一种情况,在笔试和面试中也经常会碰到,借此对这个问题进行整理分享。
定义
在Android上,如果应用程序有一段时间响应不够灵敏,系统会向用户显示一个对话框,这个对话框称作应用程序无响应(ANR:Application Not Responding)对话框。用户可以选择“等待”而让程序继续运行,也可以选择“强制关闭”。所以一个流畅的合理的应用程序中不能出现ANR,让用户看到ANR是一个极度不友好的用户体验。因此,在程序里对响应性能的设计很重要,这样系统不会显示ANR给用户。默认情况下,在Android中Activity的最长执行时间是5秒,BroadcastReceiver的最长执行时间则是10秒。
类型
- KeyDispatchTimeout(5 seconds) –主要类型按键或触摸事件在特定时间内无响应
- BroadcastTimeout(10 seconds) –BroadcastReceiver在特定时间内无法处理完成
- ServiceTimeout(20 seconds) –小概率类型 Service在特定的时间内无法处理完成
原因
超时时间的计数一般是从按键分发给app开始。超时的原因一般有两种:
(1)当前的事件没有机会得到处理(即UI线程正在处理前一个事件,没有及时的完成或者looper被某种原因阻塞住了)
(2)当前的事件正在处理,但没有及时完成
分析
- 首先分析log
- 从trace.txt文件查看调用stack.
- 看代码
- 仔细查看ANR的成因
查看trace.txt文件
$chmod 777 /data/anr
$rm /data/anr/traces.txt
$ps
$kill -3 PID
//adbpull data/anr/traces.txt ./mytraces.txt
解决
- 减少在UI主线程中设计耗时的操作,例如数据库操作,网络连接操作(android2.3以后已经禁止在UI主线程中进行网络操作)
- 通过异步编程,通知UI主线程,避免对UI主线程进行阻塞
- 耗时的工作(比如数据库操作,I/O,连接网络或者别的有可能阻碍UI线程的操作)把它放入单独的线程处理
- 尽量用Handler来处理UI主线程和其他线程之间的交互
UI主线程
- Activity:onCreate(), onResume(), onDestroy(), onKeyDown(), onClick(),etc
- AsyncTask: onPreExecute(), onProgressUpdate(), onPostExecute(), onCancel,etc
- Mainthread handler: handleMessage(), post*(runnable r), etc
- other
具体实例参考
http://www.cnblogs.com/purediy/p/3225060.html
http://blog.youkuaiyun.com/leilu2008/article/details/6689405
http://www.cnblogs.com/wanqieddy/archive/2012/05/04/2482661.html