使用android手机的时候,有时候会出现卡屏,无法动弹的情况。本文就简单的说明一下程序无响应的问题。
浅谈Android ANR
ANR is Application Not Responding.
现象
用户感知为程序长时间无法响应,Android系统自身会弹出一个对话框,告知需要等待,还是杀死程序。
原因
应用程序主线程在超时时间内对输入事件没有处理完毕,或者对特定操作没有执行完毕,就会出现ANR。
ANR的类型
- KeyDispatchTimeout(5 seconds)
主要类型,系统会显示对话框提示。按键或触摸事件在特定时间内无响应。
可能出现的两种情况
1,用户输入事件处理超时;2,窗口获取焦点超时
BroadcastTimeout(10 seconds)
系统仅仅输出log而已,BroadcastReceiver在特定时间内无法处理完成
ServiceTimeout(20 seconds)
系统仅仅输出log而已,Service在特定时间内无法处理完成
ContentProvider相关操作执行超时,(I/O耗时操作),在UI线程中进行网络操作,也容易引发ANR。
解决套路
- 第一种情况
Log提示语:Reason:Input dispatching timed out(Waiting because the focused window has not finished processing the input events that were previously delivered to it);
产生这种ANR的前提是要有输入事件,如果用户没有触发任何输入事件,即使是主线程阻塞,也不会产生ANR,因为InputDispatcer没有分发事件给应用程序,所以不会检测处理超时,以及报告ANR。
- 第二种情况:
Log提示语:Reason:Input dispatching timed out(Waiting because no window has focus but there is a focused application that may eventually add a window when it finishes starting up);
如何避免KeyDispatchTimeout
1:UI线程尽量只做跟UI相关的工作
2:耗时的工作(比如数据库操作,I/O,连接网络或者别的有可能阻碍UI线程的操作)把它放入单独的线程处理
3:尽量用Handler来处理UIthread和别的thread之间的交互
android的一些耗时操作
- 数据库操作。数据库操作尽量采用异步方法做处理。
- 初始化的数据和控件太多。
- 频繁的创建线程或者其他大对象。
- 加载过大数据和图片
- 对大树据排序和循环操作
- 过多的广播和滥用广播
- 大树据的传递和共享
- 访问网络
- 避免在循环中创建对象。
最后一点小体会
Thread.sleep();表示主动休眠,无论你设置为多长时间,只要你在睡眠的时候,不进行其他的操作,都不会造成anr。
如果你在代码中,直接引用Thread, 在ui线程中,就是ui thread。在子线程中,就是子线程 thread。
直接new Thread().start().这个就是创建一个子线程,ui线程和子线程会一起执行。如果对同一个资源进行操作,所以才会产生死锁现象