1、前言
ANR
对于Android
开发者来说一定不会陌生,从刚开始学习Android
时的一不注意就ANR
,到后来知道主线程不能进行耗时操作注意到这点后,程序出现ANR
的情况就大大减少了,甚至于消失了。那么真的是只要在主线程做耗时操作就会产生ANR
吗?为什么在有时候明明觉得自己没在主线程做耗时操作也出现了ANR
呢?一旦出现莫名其妙的ANR
,怎么定位导致ANR
的产生的位置和解决问题呢?那么接下来就来一个个的解决这些问题。
2、ANR是什么?
ANR
全称Application Not Responding
即应用程序无响应。在Android
中如果应用程序有一段时间无法响应用户操作,系统会弹出弹窗,让用户选择是继续等待还是强制关闭程序。一款良好应用APP
是不应该出现这个弹窗的。
3、ANR的产生原因
ANR
产生原因和类型有以下几种:
1、Activity
在5秒钟之内无法响应屏幕触摸事件挥着键盘输入事件就会产生ANR
。
KeyDispatchTimeout
Reason:Input event dispatching timed out
2、BroadcastReceiver
在10秒钟之内还未执行完成就会产生ANR
。
BroadcastTimeout
Reason:Timeout of broadcast BroadcastRecord
3、Service
各个生命周期在20秒钟之内没有执行完成就会产生ANR
。
ServiceTimeout
Reason:Timeout executing service
4、ContentProvider
在10秒钟之内没有执行完成就会产生ANR
。
ContentProviderTimeout
Reason:timeout publishing content providers
在以上这几种原因中出现最多的一般是第一种,而且往往都是因为在写代码时不注意,在主线程做了耗时的操作。
4、ANR的定位与解决
关于ANR
的定位这里举一个例子来看。这是我之前遇到的一次出现ANR
的时候所解决问题的情况和解决步骤。
首先当然是复现ANR
现象,找准ANR
出现的地方,查看对应代码,如果能直接看出来问题所在,找到代码中做的错误操作那么直接修改相应代码就解决问题了。但是如果没法轻易看出问题原因,接下来就只好去Logcat
中查看对应的错误日志。
07-22 21:39:17.019 819-851/? E/ActivityManager: ANR in com.xxxx.performance (com.xxxx.performance/.view.home.activity.MainActivity)
PID: 7398
Reason: Input dispatching timed out (com.xxxx.performance/com.xxxx.performance.view.home.activity.MainActivity, Waiting to send non-key event becaus