Android ANR产生原因和解决办法
ANR (Application Not Responding)
ANR定义:在Android上,如果你的应用程序有一段时间响应不够灵敏,系统会向用户显示一个对话框,这个对话框称作应用程序无响应(ANR:Application Not Responding)对话框。用户可以选择“等待”而让程序继续运行,也可以选择“强制关闭”。所以一个流畅的合理的应用程序中不能出现anr,而让用户每次都要处理这个对话框。因此,在程序里对响应性能的设计很重要,这样系统不会显示ANR给用户。
ANR分类:
一般分为3种:
1:KeyDispatchTimeout(5 seconds) –主要情况 :按键或触摸事件在特定时间内无响应
2:BroadcastTimeout(10 seconds) :BroadcastReceiver在特定时间内无法处理完成
3:ServiceTimeout(20 seconds) –小概率类型 : Service在特定的时间内无法处理完成(所以虽然service是后台执行的,但是他是运行在UI线程的,如果处理一些耗时操作,会造成ANR)
1:KeyDispatchTimeout(5 seconds) –主要情况 :按键或触摸事件在特定时间内无响应
2:BroadcastTimeout(10 seconds) :BroadcastReceiver在特定时间内无法处理完成
3:ServiceTimeout(20 seconds) –小概率类型 : Service在特定的时间内无法处理完成(所以虽然service是后台执行的,但是他是运行在UI线程的,如果处理一些耗时操作,会造成ANR)
再细分的话ANR可能是由主线程导致也可能是由非主线程导致:
由于主线程导致的情况:
1.耗时网络访问
2.当有大量数据读写操作时再请求数据读写
3.数据库操作(比如其他大数据量应用访问数据库导致数据库负载过重时)
4.硬件操作(比如Camera)
5.调用thread_join() / Sleep() / Wait() 或者等待locker的时候
6.Service binder 数量达到上限
7.在system_server中发生WatchDog ANR
8.Service忙导致超时无响应
由于非主线程导致的情况:
1.非主线程持有lock,导致主线程等待lock超时
2.非主线程终止或者崩溃导致主线程一直等待
避免ANR:
1、主线程中,程序应该尽量少进行程序执行,Activity应该在它的关键生命周期方法(如onCreate()和onResume())里尽可能少的去做创建操作。(可以采用重新开启子线程的方式,然后使用Handler+Message的方式做一些操作,比如更新主线程中的ui等)
2、应用程序应该避免在BroadcastReceiver里做耗时的操作或计算。但不要在子线程里去做这些事情(因为 BroadcastReceiver的生命周期短)。而应该让应用程序应该启动一个 Service。
3、避免在Intent Receiver里启动一个Activity,因为它会创建一个新的画面,并从当前用户正在运行的程序上抢夺焦点。如果你的应用程序在响应Intent广 播时需要向用户展示什么,你应该使用Notification Manager来实现。
2、应用程序应该避免在BroadcastReceiver里做耗时的操作或计算。但不要在子线程里去做这些事情(因为 BroadcastReceiver的生命周期短)。而应该让应用程序应该启动一个 Service。
3、避免在Intent Receiver里启动一个Activity,因为它会创建一个新的画面,并从当前用户正在运行的程序上抢夺焦点。如果你的应用程序在响应Intent广 播时需要向用户展示什么,你应该使用Notification Manager来实现。