什么是ANR:
ANR,Applicaion Not Responding,及程序未响应。发生ANR时系统会显示一个dialog,提示用户选择“等待”或者“强制关闭”,结束应用。ANR同崩溃一样,在开发过程中应该避免的。
什么会触发ANR:
- 主线程被IO操作阻塞(不要在UI线程进行IO操作)
- 主线程存在耗时的操作。
- 主线程中错误操作。如Thread.wait()或者Thread.sleep()等。
在Android中,应用程序的响应是受到Activity Manager和Window Manager系统服务的,一旦出现以下情况,就会出现dialog:
1.在5秒内没有出现相应的操作。(No response to an input event(such as key press or screen touch events)within 5 seconds.)
2.广播接收器在10s之内没有执行完成。(A BroadcastReceiver hasn’t finished executing seconds)
怎样避免ANR
Android中的线程通常都是在UI(UI Thread)或者主线程(Main Thread)中,也就是说你在主线程中操作任何耗时的操作都可能发生ANR.因此在主线程中任何操作都应该尽快完成。
1.在Activty的生命周期中的关键方法,例如onCreate()和onResume()中尽可能少的工作。
2.使用AsyncTask处理耗时操作(网络请求和数据操作等)。
3.如果使用了Thread或者HandlerThread,确保主线程不会在等待工作线程完成时被阻塞,也就是不会触发Thread.wait()或者Thread.sleep(),应该使用Handler处理工作线程的结果。
4.在BroadcastReceiver中完成那些小而散(smart或者discrete)的工作,而不是那些长时间耗时或计算的工作,如果需要交给IntentService去完成。
技巧提高
通常0.1或者0.2秒是用户认为应用缓慢的阈值。以下是一些tips(技巧),可以避免ANR和及时响应用户:
- 如果应用正在处理用户后台的输入,应该告知用户处理的进度,可以在UI线程中ProgressBar.
- 特别的,如果是游戏应用的话,计算工作应该在工作进程(WorkThread)中完成。
- 如果在初始化中进行耗时的操作,可也考虑使用欢迎页面(splash screen)或者提示用户正在尽快加载,同时显示加载进度信息。这样用户才不会认为你的程序停滞了(forzen).
- 使用Systrace和Traceview来定位应用中响应用户的瓶颈的位置。