Service的启动过程
Service的启动和根Activity的启动很类似。Service的启动同样需要保证该应用程序的进程已经被启动。
启动大纲
-
ContextImpl请求AMS启动Service.
-
AMS请求ActivityThread启动Service.
ContextImpl请求AMS启动Service

-
当我们需要启动一个Service时,我们会使用
context.startService。而Context只是一个抽象的类,它的实现是在ContextWrapper中。 -
在ContextWrapper的
startService方法中,又会调用其内部的Context类型的mBase变量,而该变量的创建详见ActivityThread的createBaseContextForActivity方法,它的实现类是ContextImpl。 -
在ContextImpl的
startService方法中,又会调用其自身的startServiceCommon方法。 -
在ContextImpl的
startServiceCommon方法中,会使用ActivityManager获取AMS的代理IActivityManager,并调用其startService方法。
AMS请求ActivityThread启动Service

-
AMS的
startService方法中调用ActiveService的startServiceLocked方法,其中调用retrieveServiceLocked用于获取启动服务的Intent参数所对应的ServiceRecord,它主要用于描述一个Service,启动Service所必须的参数。 -
在ActiveService的
startServiceLocked方法中获取到相应的ServiceRecord之后,就会调用其自身的startServiceInnerLocked方法,而它又会去调用bringUpServiceLocked方法。在bringUpServiceLocked方法中主要做了以下三个工作:
(1)获取Service运行所在的进程。
(2)如果Service运行所在的应用程序进程ProcessRecord存在,则调用其自身的realStartServiceLocked方法来启动Service.
(3)如果Service运行所在的应用程序进程ProcessRecord不存在,则需要调用AMS的startProcessLocked方法来启动应用程序进程。
-
在ActiveService的
realStartServiceLocked方法中,会使用ProcessRecord的IApplicationThread类型的引用(实现类是ActivityThread的内部类ApplicationThread),调用其scheduleCreateService方法。 -
在ActivityThread的
scheduleCreateService方法中,会向其内部类并继承自Handler的H发送CREATE_SERVICE消息,并由H进行处理,最终会调用handleCreateService方法。 -
在ActivityThread的
handleCreateService方法中主要做了如下几件事:
(1)获取要启动Service的应用程序的LoadApk(包信息),并通过它获取类的加载器,通过反射创建Service的实例。
(2)调用ContextImpl的createAppContext方法,为Service创建上下文环境ContextImpl对象。
(3)调用Service的attach方法,对Service进行初始化。
(4)调用Service的onCreate方法,这样Service就启动了。
Service的绑定过程
除了使用Context的startService来启动Service外,我们也可以通过Context的bindService来绑定Service。绑定Service的过程要比启动Service的过程复杂一些。
启动大纲
-
ContextImpl请求AMS绑定Service.
-
AMS请求ActivityThread处理Service绑定.
-
AMS进行Service的绑定.
ContextImpl请求AMS绑定Service

-
当我们需要绑定一个Service时,我们会使用
context.bindService。而Context只是一个抽象的类,它的实现是在ContextWrapper中。 -
在ContextWrapper的
bindService方法中,又会调用其内部的Context类型的mBase变量,而该变量的创建详见ActivityThread的createBaseContextForActivity方法,它的实现类是ContextImpl。 -
在ContextImpl的
bindService方法中,又会调用其自身的bindServiceCommon方法。 -
在ContextImpl的
bindServiceCommon方法中,首先调用LoadedApk的getServiceDispatcher方法获取ServiceConnection的封装类(本地的代理)IServiceConnection(用于跨进程通信),然后使用ActivityManager获取AMS的代理IActivityManager,调用其bindService方法并将IServiceConnection对象传入。
AMS请求ActivityThread处理Service绑定

-
AMS的
bindService方法中调用方法中调用ActiveService的bindServiceLocked方法,其中同样的和startServiceLocked一样调用retrieveServiceLocked用于获取启动服务的Intent参数所对应的ServiceRecord,然后调用ServiceRecord的retrieveAppBindingLocked方法来获取应用和服务的绑定信息AppBindRecord,最后调用requestServiceBindingLocked方法,将之前获取的AppBindRecord信息传入,来发出服务绑定的请求。 -
除此之外,在
bindServiceLocked方法调用requestServiceBindingLocked请求绑定前,还调用了bringUpServiceLocked方法去启动服务。 -
在ActiveService的
requestServiceBindingLocked方法中最终会调用ActivityThread的scheduleBindService方法,然后封装BindServiceData数据并将其传入sendMessage方法中,向H发送BIND_SERVICE消息。在H对应的消息处理中会调用handleBindService方法。在handleBindService方法中,对未绑定服务的,先后调用Service的onBind方法和AMS的publishService方法;对已绑定服务的,先后调用Service的onRebind方法和AMS的serviceDoneExecuting方法。

-
在AMS的publishService方法中又调用了
ActiveService的publishServiceLocked方法。 -
在
publishServiceLocked方法中会调用IServiceConnection的connected方法来建立服务连接,最终会调用执行LoadApk中的RunConnection任务,执行doConnected方法建立服务绑定连接。
与Service绑定相关的对象类型介绍:
-
ServiceRecord:用于描述一个Service。
-
ProcessRecord:一个进程所包含的信息。
-
ConnectionRecord:用于描述应用程序进程和Service建立的一次通信。
-
AppBindRecord: 用于维护Service与应用进程之间的绑定信息。
-
IntentBindRecord:用于描述绑定Service的Intent信息。
联系方式

微信公众号
