1.ANR有哪几种?
从ActivityManagerService的实现可以看到,ANR有四种,分别对应Android的四个fundermetals。这个也不难理解:所有fundermetal都会在main thread上运行,如果超过了响应的间隔,那么就会ANR。另外JNI调用native函数时也会发生无响应,不过我觉得应该不算单独的一种,它只是未响应发生在了native里,而不是vm里。
2.ANR是什么?
从ActivityManagerService可以看到,作为一个manager类,要去检测所管理的对象是否处于可相应状态,一个不错的方式就是给那个对象发消息,并等待回调。事实上,就是这么做的。每隔一段时间,manager会发消息给所有fundamental,这个消息格式固定,同时带一个delay time,譬如说activity的delay time就是5000ms,当消息发出之后,5000ms之内没有收到相应,那么manager就要把那个activity ANR掉。对于broadcast receiver、provider和service也是同样的,只是delay time不一样。
以Activity为例,几个负责Activity生命周期的回调方法(以on开头的那几个),被调用后,5000ms内没有返回,那么就ANR鸟。另外还有key dispatch ANR,也就是说,当用户点击了进行了某些操作产生key event了,那么应用就必须在规定时间处理key event,如果超时,会立刻ANR。
3.ANR的导致原因
我叙述一下google I/O 2010上一个presentation上说的:就是性能问题。我们知道,一般情况下,Android系统的瓶颈经常在I/O操作,无论是本地还是网络,经常会导致程序看起来不那么顺畅,如果达到某个时间没有响应,那么就ANR鸟。我猜测,
4.如何避免ANR
"Never never never do slow things on main thread".我引用了那个presentation的原话。
5.如何解决ANR的问题
上面介绍了ANR的一些基本知识,但是在现实问题中,ANR的问题经常会比较难解决。而且每一种ANR在logcat的信息中都会有不同的。如果要了解不同ANR的特点,就需要些多个实例来观察log信息。这里需要关注的几个信息是,线程、内存、CPU、异常堆栈等信息。google貌似提供了工具来dump发生ANR时的系统及APP信息。