揭秘!Android-Service-ANR-的监控机制

Android系统中,ANR机制是一个比较大的话题。四大组件Activity、Service、BroadCastReceiver、ContentProvider都会涉及到。四大组件对于Anr的监控机制是不尽相同的,BroadCastReceiver和Service比较类似。Activity作为强交互的组件,有一套基于InputDispatcher的独特Anr检测机制,涉及JNI层。在这里我们的重点是:针对Service组件,在Android 系统层是如何建立Anr机制的。这里的话题涵盖以下方面:

  1. Service 的 Anr监控机制都由那些重量级角色参与
  2. Service 的 Anr监控机制的建立流程是怎样的
  3. Service 的 Anr监控机制的实现原理是什么

我们一般启动一个Service,会调用startService(),我们追进去发现,调用这句话的其实是ContextImpl这个类。ContextImpl前面我们已经讲过了,是Context的子类,跟ContextWrapper是兄弟关系。然后,它调用自己的startServiceCommon()跨进程调用到sys_server进程中的ActivityManagerService(后续简称AMS)的startService()方法申请资源。

在AMS 的startService()中,又调用到ActiveServices类(后续简称AS)中的startServiceLocked(),依次经历startServiceInnerLocked()->bringUpServiceLocked()->realStartServiceLocked()去真正执行startService的操作。

在realStartServiceLocked()中,首先执行bumpServiceExecutingLocked(),走到scheduleServiceTimeoutLocked()方法,就是在这里,Anr的监控机制,通过AMS中的Handler,埋下了一颗“延时炸弹”,并通过区分Service的前后台情况,选用不同的“引爆时长”。如果是ForegroundService,则超时时长为20s,后台则相对长一些,200s

<pre language="javascript" code_block="true">void scheduleServiceTimeoutLocked(ProcessRecord proc) {
        if (proc.executingServices.size() == 0 || proc.thread == null) {
            return;
        }
        Message msg = mAm.mHandler.obtainMessage(
                ActivityManagerService.SERVICE_TIMEOUT_MSG);
        msg.obj = proc;
        mAm.mHandler.sendMessageDelayed(msg,
                proc.execServicesFg ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT);
    }

到此,Anr机制在监控Service startService时的第一步已经迈出了,那就是,埋入一个延时消息(延时炸弹)。那么埋入了延时炸弹干什么呢?当然是为了能够在有效时间内解除这个炸弹咯。如果这个炸弹最终在延时时间内没有被移除,则Handler最终被dispatch到该消息的时候,不就触发了Anr了吗。这就是我们Anr的一个整体猜想。下面咱就验证一下这个想法吧。

在AS中的scheduleCreateService()方法,执行了bumpServiceExecutingLocked()之后,调用了app.thread.scheduleCreateService()这句话,跨进程调用到了发起startService这个进程中的ApplicationThread类,它是ActivityThread的内部类,通过Binder机制负责跨进程通信。下面是该类执行scheduleCreateService()的内容:

<pre language="javascript" code_block="true">//ApplicationThread 代码:
public final void scheduleCreateService(IBinder token,
                ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
            updateProcessState(processState, false);
            CreateServiceData s = new CreateServiceData(
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值