每日一题:Looper无限循环的阻塞为啥没有ANR


theme: awesome-green

在android面试中,我们常会遇到Framework面试相关问题,而今天要分享的就是Looper无限循环的阻塞为啥没有ANR?

其主要考察的是程序员是否了解Looper的运行机制。

一般遇到此类问题我们可以从以下两个方面去回答:

  1. Handler的内部原理
  2. 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

今日分享到此结束,下期更精彩~

关注个人简介,面试不迷路~

你可能感兴趣的:(每日一题:Looper无限循环的阻塞为啥没有ANR)