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

Service的启动过程

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

启动大纲

  1. ContextImpl请求AMS启动Service.

  2. AMS请求ActivityThread启动Service.


ContextImpl请求AMS启动Service

在这里插入图片描述

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

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

  • ContextImplstartService方法中,又会调用其自身的startServiceCommon方法。

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

AMS请求ActivityThread启动Service

在这里插入图片描述

  • AMSstartService方法中调用ActiveServicestartServiceLocked方法,其中调用retrieveServiceLocked用于获取启动服务的Intent参数所对应的ServiceRecord,它主要用于描述一个Service,启动Service所必须的参数。

  • 在ActiveService的startServiceLocked方法中获取到相应的ServiceRecord之后,就会调用其自身的startServiceInnerLocked方法,而它又会去调用bringUpServiceLocked方法。在bringUpServiceLocked方法中主要做了以下三个工作:

(1)获取Service运行所在的进程。

(2)如果Service运行所在的应用程序进程ProcessRecord存在,则调用其自身的realStartServiceLocked方法来启动Service.

(3)如果Service运行所在的应用程序进程ProcessRecord不存在,则需要调用AMS的startProcessLocked方法来启动应用程序进程。

  • ActiveServicerealStartServiceLocked方法中,会使用ProcessRecordIApplicationThread类型的引用(实现类是ActivityThread的内部类ApplicationThread),调用其scheduleCreateService方法。

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

  • ActivityThreadhandleCreateService方法中主要做了如下几件事:

(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

在这里插入图片描述

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

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

  • ContextImplbindService方法中,又会调用其自身的bindServiceCommon方法。

  • ContextImplbindServiceCommon方法中,首先调用LoadedApkgetServiceDispatcher方法获取ServiceConnection的封装类(本地的代理)IServiceConnection(用于跨进程通信),然后使用ActivityManager获取AMS的代理IActivityManager,调用其bindService方法并将IServiceConnection对象传入。

AMS请求ActivityThread处理Service绑定

在这里插入图片描述

  • AMSbindService方法中调用方法中调用ActiveServicebindServiceLocked方法,其中同样的和startServiceLocked一样调用retrieveServiceLocked用于获取启动服务的Intent参数所对应的ServiceRecord,然后调用ServiceRecordretrieveAppBindingLocked方法来获取应用和服务的绑定信息AppBindRecord,最后调用requestServiceBindingLocked方法,将之前获取的AppBindRecord信息传入,来发出服务绑定的请求。

  • 除此之外,在bindServiceLocked方法调用requestServiceBindingLocked请求绑定前,还调用了bringUpServiceLocked方法去启动服务。

  • ActiveServicerequestServiceBindingLocked方法中最终会调用ActivityThreadscheduleBindService方法,然后封装BindServiceData数据并将其传入sendMessage方法中,向H发送BIND_SERVICE消息。在H对应的消息处理中会调用handleBindService方法。在handleBindService方法中,对未绑定服务的,先后调用Service的onBind方法和AMS的publishService方法;对已绑定服务的,先后调用Service的onRebind方法和AMS的serviceDoneExecuting方法。

在这里插入图片描述

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

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

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

  • ServiceRecord:用于描述一个Service。

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

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

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

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


联系方式

在这里插入图片描述

微信公众号

在这里插入图片描述

发布了61 篇原创文章 · 获赞 103 · 访问量 11万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 点我我会动 设计师: 上身试试

分享到微信朋友圈

×

扫一扫,手机浏览