回答这个问题先来了解一下下面几个点
-
1.什么是ANR? ANR发生的原因是什么?
ANR 即 Application Not responding ,应用程序无响应
在android中,一般情况下,四大组件均是工作在主线程的,Android中的ActivityManager和WindowManager会随时监控应用程序的响应情况,如果因为一些耗时操作(网络请求或者IO操作)造成主线程阻塞一定时间(例如造成5s内不能响应用户事件或者BroadcastReceiver的onReceive方法执行时间超过10s),那么系统就会显示ANR对话框提示用户对应的应用处于无响应状态。
主线程Looper从消息队列中读取消息,当读完所有消息时,主线程阻塞,子线程往消息队列发送消息,并且往管道文件写数据,主线程即被唤醒, 从管道文件读取数据,主线程被唤醒只是为了读取消息,当消息读取完毕,再次睡眠,因此loop的循环并不会对cpu性能有过多的 消耗。 -
2. Looper为什么要无限循环?
Looper在prepare中通过ThreadLocal保证了每个线程Looper对象的唯一性,即对于每个线程,有唯一的Looper对象和MessageQueue队列
主线程中如果没有looper进行循环,那么主线程一运行完毕就会退出,Looper主要是做消息循环,然后由Handler进行消息分发处理,一旦退出消息循环,那么应用程序也就退出了。
主线程在main方法中开了一个阻塞式死循环,保证我们的应用程序不会退出
ANR的原因是因为Looper对象MessageQueue队列中的事件没有能够得到及时执行
两方面回答:
- 死循环不是造成ANR的必然原因,ANR是因为消息队列当中的事件没有及时得到处理造成的。(但是我们写个死循环,基本上都会造成ANR,原因是主线程一直在这里循环,后面的事件没有得到及时处理)
- 主线程的Looper循环,不会ANR最多就是OOM
参考链接:
网友评论