Service启动流程

Service有两种使用方式,本文分析startService情况下Service的执行流程

通过源码分析我们要解决以下问题:

  1. Service是如何创建的?
  2. Service的onCreate, onStartCommand怎么被执行的
  3. Service启动涉及哪些环节?

时序图

通过分析源码,我们提取核心的调用流程,其中深红色箭头代表发生了跨进程调用

service start flow

核心环节分析

整个调用流程横跨了较多类,我们简单归一下档

ContextWrapper, ContextImpl

作为顶层入口,提供了Service启动的调用API,如startService, bindService;

ActivityManagerService

系统服务,经常被称作AMS,App调用AMS是通过Binder机制实现的,AMS是系统服务。在这里提供了startService服务。

ActivityServices

工具类,负责实现AMS提供的API具体逻辑,比如AMS启动Service的API是startService,这个函数内部会执行AcitivtyServices的startServiceLocked, 从而将控制权转移到了ActivityServices中,根据启动service的上下文情况,陆续调用了其他函数:

  • startServiceInternalLocked
  • bringupServiceLocked
  • realStartServiceLocked --> 跨进程调用scheduleCreateService
  • sendServiceArgsLocked --> 跨进程调用scheduleServiceArgs

其中的两处跨进程操,会调用到ApplicationThread,他们分别是:

  • 触发service创建流程的scheduleServiceCreate
  • 触发serice生命周期onStartCommand

小结

现在我们解答一下开篇的疑问:

1. Service是如何创建的?

在上下文中,利用ContextWrapper提供的startService函数,经过一次Binder通信,调用到了系统的AMS服务,AMS服务通过工具类ActivityServices进行了上下文的处理,然后在经历一次Binder跨进程通信,将创建Service的动作通过Handler的消息发送给了ActivityThread.H, H这个Handler在handleMessage之后最终通过反射,用ClassLoader构造了Service实例。

2. Service的onCreate, onStartCommand怎么被执行的

在Handler处理过程中,创建完Service实例后,首先执行了serive的attach方法,然后在调用了onCreate方法。 至于onStartCommand,是在scheduleServiceArgs时触发。属于第二次跨进程调用的操作内容,类似的将SERVICE_ARGS消息发送给了ActivityThread.H,H这个Handler在handleMessage之后,通过缓存map,利用IBinder作为key,获取了上一步已经创建过的Service,然后执行Service的onStartCommand方法。

3. Service启动涉及哪些环节?

在Service启动过程汇总,先会尽量多次跨进程操作,包括向AMS发起startService的操作,以及AMS向目标App的ApplicationThread发起真正的Service创建,Service生命周期调用。

powered by Gitbook最近更新 2019-10-25

results matching ""

    No results matching ""