Android源码分析--Service的启动和绑定

Service的启动过程

Service的启动和根Activity的启动很类似。Service的启动同样需要保证该应用程序的进程已经被启动。

启动大纲

  1. ContextImpl请求AMS启动Service.

  2. AMS请求ActivityThread启动Service.


ContextImpl请求AMS启动Service

Android源码分析--Service的启动和绑定_第1张图片

  • 当我们需要启动一个Service时,我们会使用context.startService。而Context只是一个抽象的类,它的实现是在ContextWrapper中。

  • 在ContextWrapper的startService方法中,又会调用其内部的Context类型的mBase变量,而该变量的创建详见ActivityThread的createBaseContextForActivity方法,它的实现类是ContextImpl

  • 在ContextImpl的startService方法中,又会调用其自身的startServiceCommon方法。

  • 在ContextImpl的startServiceCommon方法中,会使用ActivityManager获取AMS的代理IActivityManager,并调用其startService方法。

AMS请求ActivityThread启动Service

Android源码分析--Service的启动和绑定_第2张图片

  • 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方法中,会使用ProcessRecordIApplicationThread类型的引用(实现类是ActivityThread的内部类ApplicationThread),调用其scheduleCreateService方法。

  • 在ActivityThread的scheduleCreateService方法中,会向其内部类并继承自Handler的H发送CREATE_SERVICE消息,并由H进行处理,最终会调用handleCreateService方法。

  • 在ActivityThread的handleCreateService方法中主要做了如下几件事:

(1)获取要启动Service的应用程序的LoadApk(包信息),并通过它获取类的加载器,通过反射创建Service的实例。

(2)调用ContextImplcreateAppContext方法,为Service创建上下文环境ContextImpl对象。

(3)调用Serviceattach方法,对Service进行初始化。

(4)调用ServiceonCreate方法,这样Service就启动了。


Service的绑定过程

除了使用Context的startService来启动Service外,我们也可以通过Context的bindService来绑定Service。绑定Service的过程要比启动Service的过程复杂一些。

启动大纲

  1. ContextImpl请求AMS绑定Service.

  2. AMS请求ActivityThread处理Service绑定.

  3. AMS进行Service的绑定.


ContextImpl请求AMS绑定Service

Android源码分析--Service的启动和绑定_第3张图片

  • 当我们需要绑定一个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绑定

Android源码分析--Service的启动和绑定_第4张图片

  • 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方法。

Android源码分析--Service的启动和绑定_第5张图片

  • 在AMS的publishService方法中又调用了ActiveService的publishServiceLocked方法。

  • publishServiceLocked方法中会调用IServiceConnectionconnected方法来建立服务连接,最终会调用执行LoadApk中的RunConnection任务,执行doConnected方法建立服务绑定连接。

与Service绑定相关的对象类型介绍:

  • ServiceRecord:用于描述一个Service。

  • ProcessRecord:一个进程所包含的信息。

  • ConnectionRecord:用于描述应用程序进程和Service建立的一次通信。

  • AppBindRecord: 用于维护Service与应用进程之间的绑定信息。

  • IntentBindRecord:用于描述绑定Service的Intent信息。


联系方式

Android源码分析--Service的启动和绑定_第6张图片

微信公众号

Android源码分析--Service的启动和绑定_第7张图片

你可能感兴趣的:(Android源码分析,Android基础,源码分析)