Service的启动过程
这部分与上一部分 根activity启动有部分相似
另外Service启动过程涉及上下文Context的知识点,这里只关注流程而不会详细介绍Contex
Service的启动过程将分为两个部分来进行讲解,分别是
ContextImpl到ActivityManageService的调用过程
和
ActivityThread启动Service
ContextImpl到AMS的调用过程
过程不是很长
流程图

如果要启动service 需要调用ContextWrapper中的startService
可以看到好像是继承自context的
调用mBase的startService方法,Context类型的mBase对象具体指的是什么呢

在四之一学过,ActivityThread启动Activity时会调用如下代码创建Activity的上下文环境
这个注释一处创建context 然后绑定activity和context

这个上下文对象appContext的具体类型是什么?我们接着查看createBaseContextForActivity方法

其中的appcontext的具体类型ContextImpl,在Activity的attach方法中将ContextImpl赋值给ContextWrapper的成员变量mBase,、
因此,上面提出的问题就得到了解答,mBase具体指向的就是ContextImpl。
所以上面的就变成了ContextImpl.startservice了
紧接着来查看ContextImpl的startService方法

在startService方法中会返回startServiceCommon方法,在startServiceCommon方法中会在注释1处调用AMS的代理IActivityManager的startService方法,最终调用的是AMS的startService方法
只要晓得最后调用到AMS的startservice就可以了
ActivityThread启动Service
这玩意相对复杂一点
时序图
其实说实话 感觉和activity的创建还蛮像的

查看AMS的startService方法
调用mServices的startServiceLocked方法,mServices的类型是ActiveServices,

ActiveServices的startServiceLocked方法代码如下所示:

- 注释1处的retrieveServiceLocked方法会查找是否有与参数service对应的ServiceRecord,如果没有找到,就会调用PackageManagerService去获取参数service对应的Service信息,并封装到ServiceRecord中,最后将ServiceRecord封装为ServiceLookupResult返回。其中ServiceRecord用于描述一个Service,和此前讲过的ActivityRecord类似。
- 在注释2处通过注释1处返回的ServiceLookupResult得到参数service对应的ServiceRecord,并传入到注释3处的startServiceInnerLocked方法中。
下面来到startServiceInnerLocked

又调用了bringUpServiceLocked方法 这玩意更长一点


- 在注释1处得到ServiceRecord 的processName值并赋给procName,其中processName用来描述Service想要在哪个进程中运行,默认是当前进程,我们也可以在AndroidManifest文件中设置android:process 属性来新开启一个进程运行Service。
- 在注释2处将procName和Service的uid传入到AMS的getProcessRecordLocked 方法中,查询是否存在一个与Service对应的ProcessRecord类型的对象app,ProcessRecord主要用来描述运行的应用程序进程的信息。
- 在注释5处判断Service对应的app为null则说明用来运行Service的应用程序进程不存在,
- 则调用注释6处的AMS的startProcessLocked方法来创建对应的应用程序进程,关于创建应用程序进程请查看第3章的内容,这里只讨论没有设置android:process属性,即应用程序进程存在的情况。
- 在注释3处判断如果用来运行Service的应用程序进程存在,
- 则调用注释4处的realStartServiceLocked方法启动service
关键在于realStartServiceLocked

其中调用了app.thread的scheduleCreateService方法。
类似activity
其中app.thread是IApplicationThread 类型的,它的实现是ActivityThread的内部类ApplicationThread。ApplicationThread的scheduleCreateService方法如下所示

scheduleLaunchActivity方法将启动Service的参数封装成ActivityClientRecord,sendMessage方法向H类发送类型为CREATE_SERVICE的消息,并将ActivityClientRecord传递过去,这个过程和4.1.3节ActivityThread启动Activity的过程是类似的。sendMessage方法有多个重载方法,
最终调用的sendMessage方法如下所示

这里的mh指的是H,它是ActivityThread的内部类并继承自**Handler **是应用程序进程中主线程的消息管理类
查看H的handleMessage方法:

handleMessage 方法根据消息类型为CREATE_SERVICE,会调用handleCreateService方法:

可以看到是一些具体的创建service流程了
在注释1处获取要启动Service的应用程序的LoadedApk,LoadedApk是一个APK文件的描述类。
在注释2处通过调用LoadedApk的getClassLoader方法来获取类加载器。
接着在注释3处根据CreateServiceData对象中存储的Service信息,创建Service实例。
在注释4处创建Service的上下文环境ContextImpl对象。
在注释5处通过Service的attach方法来初始化Service。
在注释6处调用Service的onCreate方法,这样Service就启动了。
在注释7处将启动的Service加入到ActivityThread的成员变量mServices中,其中mServices是ArrayMap类型。
结束 再放一遍这个时序图

