彻底理解Android ANR机制 一篇就够了

彻底理解Android ANR机制 一篇就够了

不论从事安卓应用开发,还是安卓系统研发,应该都遇到应用无响应(ANR,Application Not Responding)问题,当应用程序一段时间无法及时响应,则会弹出ANR对话框,让用户选择继续等待,还是强制关闭。

绝大多数人对ANR的了解仅停留在主线程耗时或CPU繁忙会导致ANR。面试过无数的候选人,几乎没有人能真正从系统级去梳理清晰ANR的来龙去脉,比如有哪些路径会引发ANR? 有没有可能主线程不耗时也出现ANR?如何更好的调试ANR?

如果没有深入研究过Android Framework的源代码,是难以形成对ANR有一个全面、正确的理解。研究系统源码以及工作实践后提炼而来,以图文并茂的方式跟大家讲解,相信定能帮忙大家加深对ANR的理解。

一、ANR触发机制

对于知识学习的过程,要知其然知其所以然,才能做到庖丁解牛般游刃有余。要深入理解ANR,就需要从根上去找寻答案,那就是ANR是如何触发的?

ANR是一套监控Android应用响应是否及时的机制,可以把发生ANR比作是引爆炸弹,那么整个流程包含三部分组成:

埋定时炸弹:中控系统(system_server进程)启动倒计时,在规定时间内如果目标(应用进程)没有干完所有的活,则中控系统会定向炸毁(杀进程)目标。

拆炸弹:在规定的时间内干完工地的所有活,并及时向中控系统报告完成,请求解除定时炸弹,则幸免于难。

引爆炸弹:中控系统立即封装现场,抓取快照,搜集目标执行慢的罪证(traces),便于后续的案件侦破(调试分析),最后是炸毁目标。

常见的ANR有service、broadcast、provider以及input,更多细节详见理解Android ANR的触发原理,深度解析Android ANR触发原理-CSDN博客,接下来本文以图文形式分别讲解。

service超时机制

下面来看看埋炸弹与拆炸弹在整个服务启动(startService)过程所处的环节。

图解1:

客户端(App进程)向中控系统(system_server进程)发起启动服务的请求

中控系统派出一名空闲的通信员(binder_1线程)接收该请求,紧接着向组件管家(ActivityManager线程)发送消息,埋下定时炸弹

通讯员1号(binder_1)通知工地(service所在进程)的通信员准备开始干活

通讯员3号(binder_3)收到任务后转交给包工头(main主线程),加入包工头的任务队列(MessageQueue)

包工头经过一番努力干完活(完成service启动的生命周期),然后等待SharedPreferences(简称SP)的持久化;

包工头在SP执行完成后,立刻向中控系统汇报工作已完成

中控系统的通讯员2号(binder_2)收到包工头的完工汇报后,立刻拆除炸弹。如果在炸弹倒计时结束前拆除炸弹则相安无事,否则会引发爆炸(触发ANR)

更多细节详见startService启动过程分析,http://gityuan.com/2016/03/06/start-service

broadcast超时机制

broadcast跟service超时机制大抵相同,对于静态注册的广播在超时检测过程需要检测SP,如下图所示。

图解2:

客户端(App进程)向中控系统(system_server进程)发起发送广播的请求

中控系统派出一名空闲的通信员(binder_1)接收该请求转交给组件管家(ActivityManager线程)

组件管家执行任务(processNextBroadcast方法)的过程埋下定时炸弹

组件管家通知工地(receiver所在进程)的通信员准备开始干活

通讯员3号(binder_3)收到任务后转交给包工头(m

相关推荐