ANR 详解

来源:互联网 发布:键盘宏定义软件 编辑:程序博客网 时间:2024/06/05 16:30

ANR 定义


ANR 也就是 "应用无响应" ,当操作在一段时间内使得系统无法处理时,系统层面会弹出应用程序无响应对话框。(一个流畅的合理的应用程序中不能出现该对话框,所以响应性能的设计很重要,这样系统不会显示该对话框给用户。)


ANR 产生的原因


在 Android 里, App 的响应能力是由 Activity Manager 和 Window Manager 系统服务来监控的,在如下情况会弹出 ANR 对话框

KeyDispatchTimeout (5 seconds) :按键或者触摸事件在特定时间内无响应

BroadcastTimeout (10 seconds):广播接收器在特定时间内无法处理完成

ServiceTimeout (20 seconds):服务在特定时间内无法处理完成


说明:第一种情况是主要情况, 而服务相应超时是小概率类型:虽然服务是在后台执行的,但是它是运行在主线中的,如果处理一些耗时操作,也会造成 ANR。


造成以上情况的首要原因就是在主线程中做了太多的阻塞耗时操作,其次是非主线程的一些原因,举例说明。


由于主线程导致的情况:1、耗时网络操作; 2、当有大量数据读写操作时,再请求数据读写; 3、数据库操作,比如其他大数据量应用访问数据库导致数据库负载过量时;4、 硬件操作, 比如 Camera; 5、调用线程的 Join() / Sleep() / Wait() 或者等待 locker的时候; 6、 Servic binder 数量达到上限; 7、在 system_server 中发生 WatchDog ANR; 8、Service 忙导致超时无响应;


由于非主线程的情况:1、 非主线程持有 lock, 导致主线程等待 lock 超时; 2、 非主线程终止或者崩溃导致主线程一直等待


ANR 如何避免


1、主线程中,程序应该尽量少进行程序执行, 在 Activity 的关键生命周期方法中应该尽可能少的去做创建操作,如:onCreate()、 onResume() 。可以采用重新开启子线程的方式,然后使用 Handler + Message 的方式做一些操作,如:更新线程中的 UI 等 。


2、应用程序应该避免在 BroadcastReceiver 中做耗时的操作或者计算。 但不要在子线程中去做这些事情(因为广播接收器的生命之期很短) 应该让应用程序启动一个 Service。


3、避免在 Intent Receiver 中启动一个 Activity,因为它会创建一个新的画面,并从当前用户正在运行的程序上抢夺焦点。如果你的应用程序在响应 Inetent 广播时需要向用户展示什么,你应该使用 Notification Manager 来实现 。



原创粉丝点击