theme: awesome-green
在android面试中,我们常会遇到Framework面试相关问题,而今天要分享的就是Looper无限循环的阻塞为啥没有ANR?
其主要考察的是程序员是否了解Looper的运行机制。
一般遇到此类问题我们可以从以下两个方面去回答:
- Handler的内部原理
- ANR发生的原因
问题正解:
1.首先回答ANR是什么?引起ANR的主要原因有哪些?
-
ANR(Application Not Responding)是应用无响应。ndroid系统对于一些事件需要在一定的时间范围内完成,如果超过预定时间能未能得到有效响应或者响应时间过长,都会造成ANR。
-
发生ANR的主要四种情况:
1)Service Timeout:前台服务在20s内未执行完成; 2)BroadcastQueue Timeout:前台广播在10s内未执行完成 3)ContentProvider Timeout:内容提供者在publish过超时10s; 4)InputDispatching Timeout:输入事件分发超时5s,包括按键和触摸事件。
对于Service、Broadcast、Provider组件类的ANR而言,如果把发生ANR比作是引爆炸弹,那么整个流程包含三部分组成:
埋炸弹:中控系统(system_server进程)启动倒计时埋下定时器,在规定时间内如果目标(Servcie、Broadcast、Provider)没有干完所有的活,则中控系统会定向炸毁(杀进程)目标,就相当于埋下一个定时炸弹。 拆炸弹:在规定的时间内干完工地的所有活,并及时向中控系统报告完成,请求解除定时炸弹,则幸免于难。 引爆炸弹:中控系统立即封装现场,抓取快照,搜集目标执行慢的罪证(traces),便于后续调试分析,最后是炸毁目标。
对于输入超时,与其他3个组件类ANR是不同的,Input类型的超时机制并非时间到了一定就会爆炸,而是处理后续上报事件的过程才会去检测是否该爆炸,所以更像是扫雷过程。具体的逻辑是这样的:对于输入系统而言,即使某次事件执行时间超过预期的时长,只要用户后续没有再生成输入事件,那么也不需要ANR。而只有当新一轮的输入事件到来,此时正在分发事件的窗口(即App应用本身)迟迟无法释放资源给新的事件去分发,这时InputDispatcher才会根据超时时间,动态的判断是否需要向对应的窗口提示ANR信息。
那么明白了ANR的原因后,我们再来看一下Looper的阻塞原理。
2.Looper无限循环如何导致阻塞的
- Looper无限循环是Looper不停取MessageQueen中的Message并执行这个message的一种机制。我们的APP中的事件,如Activity的生命周期切换、点击、长按、滑动、都是依赖这种机制。
- 如果主线程的MessageQueue中没有消息,便会阻塞在Loop的queue.next()中的nativePollOnce方法。这个时候主线程会进入休眠状态并释放CPU资源,如果下一个消息到达或者有事物发生,通过向pipe管道写入数据来进行唤醒主线程工作。
3.Looper无限循环为啥没有ANR?
- Looper循环的阻塞是在消息队列无消息需要处理时的一种机制,这种机制就是让CPU停下来去做别的事。而且消息队列无消息,那么就是需要需要让cpu停下来,避免cpu空转,这个机制和ANR是没有关系的,完全不是同一个事,所以自然不会导致ANR
今日分享到此结束,下期更精彩~
关注博主个人简介,面试不迷路
网友评论