Android 系统Service流程
主要用到的源码文件
/frameworks/base/core/java/android/app/ContextImpl.java
和ams通信。
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
初始化Service,.管理服务 ActiveServices对象mServices
/frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
ActiveServices.ServiceMap.mServicesByIntent 存储 基于service的intent 的FilterComparison和ServiceRecord信息。
ActiveServices.ServiceMap.mServicesByInstanceName 存储 基于service的ComponentName 和ServiceRecord信息。
ActiveServices.ServiceRestarter.mService 存储ServiceRecord对象,该对象是应用bindService时 基于当前service intent创建对ServiceRecord 类对象。
/frameworks/base/core/java/android/app/LoadedApk.java
LoadedApk.ServiceDispatcher.mConnection 为应用绑定服务的ServiceConnection,
LoadedApk.ServiceDispatcher.mIServiceConnection 为 ServiceDispatcher.InnerConnection(继承IServiceConnection.Stub) 是aidl 服务端实现类对象。
一个context只会创建一次InnerConnection对象。该对象在绑定服务时候会存储在ConnectionRecord.conn,ServiceRecord.connections 的key中。
/frameworks/base/services/core/java/com/android/server/am/ServiceRecord.java
用来描述一个 Service,因为继承 Binder 可以通过aidl 跨进程传递参数。
其中 ServiceRecord.bindings ArrayMap存储Intent和IntentBindRecord.
ServiceRecord.connections 存储 IServiceConnection aidl 服务端实现类InnerConnection对象binder 和ConnectionRecord对象.
/frameworks/base/services/core/java/com/android/server/am/ProcessRecord.java
描述一个进程
/frameworks/base/services/core/java/com/android/server/am/ConnectionRecord.java
描述应用程序进程和 Service建立的一次通信,即客户端调用一次bindService会创建一个ConnectionRecord对象。
ConnectionRecord.binding 存储AppBindRecord对象。
ConnectionRecord.conn 存储 IServiceConnection aidl 服务端实现类InnerConnection对象。
/frameworks/base/services/core/java/com/android/server/am/AppBindRecord.java
应用程序进程通过Intent绑定Service时用来描述被绑定的Service,通过AppBindRecord来维护Service与应用程序进程之间的关联。
AppBindRecord.connections 存储ArraySet<ConnectionRecord> 数组。描述所有绑定通信记录的信息
AppBindRecord.intent 存储IntentBindRecord对象。
AppBindRecord.service 存储ServiceRecord对象。
AppBindRecord.client 存储ProcessRecord对象。描述谁绑定的Service
/frameworks/base/services/core/java/com/android/server/am/IntentBindRecord.java
用于描述绑定Service的Intent
注:不同的应用进程也可能会创建相同的Intent来绑定同一个Serivce。比如说一些公共的、常用的Service。
一、Service初始化
从 《AMS初始化、应用启动及activity启动流程分析(Android11)》 一文中ams 初始化流程可知。
SystemServer进程启动时SystemServer.startBootstrapServices会:
1.创建ActivityTaskManagerService并启动
2.创建ActivityManagerService并启动
调用 ActivityManagerService.Lifecycle.startService(mSystemServiceManager, atm)
ActivityManagerService.Lifecycle.startService(SystemServiceManager ssm, ActivityTaskManagerService atm) 调用ssm.startService(ActivityManagerService.Lifecycle.class).getService()
ssm为SystemServiceManager即用
SystemServiceManager.startService(Class<T> serviceClass) 。
会创建ActivityManagerService.Lifecycle对象,通过 constructor.newInstance(mContext)。
ActivityManagerService.Lifecycle.Lifecycle 调用mService = new ActivityManagerService(context, sAtm)。
ActivityManagerService.ActivityManagerService(Context systemContext, ActivityTaskManagerService atm) 构造方法。
会调用 mServices = new ActiveServices(this) 创建 ActiveServices对象mServices用来管理服务。
ActiveServices.ActiveServices(ActivityManagerService service) 调用 mAm = service 将ActivityManagerService 赋值给变量mAm。
二、启动服务 startService
Service客户端进程:
Context.startService(serviceIntent) Context是抽象类,由其子类ContextImpl实现
ContextImpl.startService(Intent service) 调用startServiceCommon(service, false, mUser)
ContextImpl.startServiceCommon(Intent service, ..) 调用 ActivityManager.getService().startService(mMainThread.getApplicationThread(), service,...)
通过aidl调用ams方法
system_server进程:
ActivityManagerService.startService(IApplicationThread caller, Intent service,...) 调用 mServices.startServiceLocked(caller, service,...)
ActiveServices.startServiceLocked(IApplicationThread caller, Intent service...) 调用startServiceLocked(caller, service,..false)
ActiveServices.startServiceLocked(IApplicationThread caller, Intent service...boolean allowBackgroundActivityStarts) 主要执行
1. 基于service对应的ServiceRecord获取ServiceLookupResult
调用res =retrieveServiceLocked(service, null, resolvedType, callingPackage,callingPid, callingUid, userId, true, callerFg, false, false)
ActiveServices.retrieveServiceLocked(Intent service,...) 基于service Intent获取或创建ServiceRecord对象后封装到ServiceLookupResult类中返回。
如果service已经启动了,从ServiceMap.mServicesByInstanceName 取出service 并返回。
如果当前service未启动, ServiceMap.mServicesByInstanceName 中当前service为空。
则基于当前service intent 调用r = new ServiceRecord(...) 创建 ServiceRecord r, 并封装到ServiceLookupResult返回。
且将相关信息保存到ServiceMap中变量 mServicesByIntent和mServicesByInstanceName中。
2. 从ServiceLookupResult取出ServiceRecord r, 调用startServiceInnerLocked(smap, service, r, callerFg, addToStarting)
ActiveServices.startServiceInnerLocked(...) 调用bringUpServiceLocked(r, service.getFlags(), callerFg, false, false)
ActiveServices.bringUpServiceLocked(ServiceRecord r...) 执行如下2步 来启动服务。
先调用 app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false) 获取service所在进程。
2.1 如果进程存在,调用 realStartServiceLocked(r, app, execInFg) 启动服务
2.2 如果进程不存在调用app=mAm.startProcessLocked(procName, r.appInfo,...) 创建并启动进程。进程创建好再启动服务。
同时调用mPendingServices.add(r) 将ServiceRecord添加到待启动服务列表mPendingServices中,
ActivityManagerService.startProcessLocked(...) 从《AMS初始化、应用启动及activity启动流程分析(Android11)》一文可知,启动进程最终会调用
ActivityManagerService.attachApplicationLocked(IApplicationThread thread,int pid, int callingUid, long startSeq) 该方法会调用mServices.attachApplicationLocked(app, processName)
ActiveServices.attachApplicationLocked(ProcessRecord proc, String processName) 遍历 mPendingServices
调用 sr = mPendingServices.get(i) 获取ServiceRecord后调用 realStartServiceLocked(sr, proc, sr.createdFromFg)启动服务
即2.1 2.2都会调用
ActiveServices.realStartServiceLocked(ServiceRecord r,ProcessRecord app, boolean execInFg) 执行2步
调用 app.thread.scheduleCreateService(r, r.serviceInfo,..)
ActivityThread. scheduleCreateService(IBinder token,ServiceInfo info..) 调用sendMessage(H.CREATE_SERVICE, s) 切换到主线程
ActivityThread.H.handleMessage(Message msg) case CREATE_SERVICE: 调用handleCreateService((CreateServiceData)msg.obj)
ActivityThread.handleCreateService(CreateServiceData data)
#1先创建service对应的Application对象,通过调用app = packageInfo.makeApplication(false, mInstrumentation) 这里mInstrumentation为空即无需调用Application.onCreate()方法.
#2 基于service信息创建Service对象,调用 service = packageInfo.getAppFactory().instantiateService(cl, data.info.name, data.intent)
#3 初始化service 调用service.attach(context, this, data.info.name, data.token, app,ActivityManager.getService())
#4 调用service的onCreate方法,调用 service.onCreate(),同时调用mServices.put(data.token, service) 将ServiceRecord 对应的IBinder 和当前启动的service对象放到mServices列表中。
三、绑定服务 bindService
Service客户端进程:
Context.bindService(serviceIntent, mConnection, Context.BIND_AUTO_CREATE) Context是抽象类,由其子类ContextImpl实现
ContextImpl.bindService(Intent service, ServiceConnection conn, int flags) 调用bindServiceCommon(service, conn, flags, null, mMainThread.getHandler(), null,getUser()) 这里instanceName为空
ContextImpl.bindServiceCommon(Intent service, ServiceConnection conn,...) 调用ActivityManager.getService().bindIsolatedService(mMainThread.getApplicationThread(),getActivityToken(), service,.sd,..)
这里的sd为 IServiceConnection aidl 服务端实现类 InnerConnection 对象mIServiceConnection。
具体是通过调用 sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags)
LoadedApk.getServiceDispatcher(ServiceConnection c,...) 调用getServiceDispatcherCommon(c, context, null, executor, flags)
LoadedApk.getServiceDispatcherCommon(ServiceConnection c,...) 调用map = mServices.get(context) 基于当前的context获取 aidl 服务端实现类InnerConnection对象mIServiceConnection,
如果存在返回该mIServiceConnection对象。
如果不存在,调用 sd = new ServiceDispatcher(c, context, handler, flags) 创建ServiceDispatcher对象,
ServiceDispatcher.ServiceDispatcher(ServiceConnection conn,...) 构造方法调用mIServiceConnection = new InnerConnection(this) 创建InnerConnection(继承IServiceConnection.Stub) 为IServiceConnection aidl 服务端实现类。
getServiceDispatcherCommon最终返回IServiceConnection aidl 服务端实现类InnerConnection对象mIServiceConnection。
即bindServiceCommon方法中sd为IServiceConnection aidl 服务端实现类InnerConnection对象mIServiceConnection。且一个context只会创建一次InnerConnection对象。
这里如果Context 是app Context则 getActivityToken为null,
bindServiceCommon方法通过aidl调用ams方法
system_server进程:
ActivityManagerService.bindIsolatedService(IApplicationThread caller, IBinder token, Intent service,. Intent service.IServiceConnection connection..) 调用mServices.bindServiceLocked(caller, token, service,...)
ActiveServices.bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,. final IServiceConnection connection,...) 主要执行如下几步
1.获取或创建service后,获取封装service的ServiceLookupResult对象 res。 调用res = retrieveServiceLocked(service,..)
ActiveServices.retrieveServiceLocked(Intent service,...) 流程同二.1
2. 先从 bindings 映射表中查找或新建 AppBindRecord, 通过调用AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp) 。
retrieveAppBindingLocked方法中 先调用filter = new Intent.FilterComparison(intent) 基于Intent创建filter,然后调用 IntentBindRecord i = bindings.get(filter) 从bindings列表获取IntentBindRecord。
如果bindings列表获取IntentBindRecord为空, 调用i = new IntentBindRecord(this, filter)创建 IntentBindRecord对象,且调用bindings.put(filter, i) 将IntentBindRecord对象添加到ServiceRecord.bindings 列表。
最后调用a = new AppBindRecord(this, i, app) 创建AppBindRecord 并返回。
即将封装了service的Intent的Intent.FilterComparison对象赋值给IntentBindRecord.intent.而AppBindRecord.intent为该IntentBindRecord对象。
然后调用ConnectionRecord c = new ConnectionRecord(b, activity,connection, ......)。
建立 binder 和 ConnectionRecord 列表及AppBindRecord的映射关系。具体流程是:
#1 调用 binder = connection.asBinder(),获取IServiceConnection aidl 服务端实现类InnerConnection对象binder 。
#2 s.addConnection(binder, c) ,将IServiceConnection aidl 服务端实现类InnerConnection对象binder 和ConnectionRecord对象存储到ServiceRecord.connections.
#3 b.connections.add(c) 将ConnectionRecord对象 添加到 AppBindRecord.connections列表中。因为不同的应用进程也可能会创建相同的Intent来绑定同一个Serivce,所以connections是列表。
3.如果flags == BIND_AUTO_CREATE 调用 bringUpServiceLocked(s, service.getFlags(), callerFg, false,permissionsReviewRequired) != null)
ActiveServices.bringUpServiceLocked(ServiceRecord r...) 同二.2 会创建进程(若进程不存在)并 启动服务。
4.如果service未绑定过(!b.intent.requested) 调用 requestServiceBindingLocked(s, b.intent, callerFg, false)
ActiveServices.requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i...) 调用r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,r.app.getReportedProcState())
这里的r为ServiceRecord(继承Binder),然后调用i.requested = true
ActivityThread.ApplicationThread.scheduleBindService(IBinder token, Intent intent,boolean rebind, int processState)
调用sendMessage(H.BIND_SERVICE, s) 这里s = new BindServiceData(),s.token = token ,s.intent = intent, token为启动服务创建的ServiceRecord对象
ActivityThread.H.handleMessage case BIND_SERVICE: 调用handleBindService((BindServiceData)msg.obj)
ActivityThread.handleBindService(BindServiceData data) 方法中
#1 调用Service s = mServices.get(data.token) 基于ServiceRecord获取Service类对象。
#2 调用 binder = s.onBind(data.intent) 这里binder为 调用Service.onBind(Intent intent) 返回的调用Service的aidl服务实现类的binder 例如:xxService = new xxService.Stub
#3 调用ActivityManager.getService().publishService(data.token, data.intent, binder),其中binder = s.onBind(data.intent)
通过aidl跨进程调用ams方法
system_server进程:
ActivityManagerService.publishService(IBinder token, Intent intent, IBinder service) 调用mServices.publishServiceLocked((ServiceRecord)token, intent, service)
ActiveServices.publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) 主要调用
#1.调用Intent.FilterComparison filter = new Intent.FilterComparison(intent) 基于Intent创建 Intent.FilterComparison对象filter。
#2.调用 IntentBindRecord b = r.bindings.get(filter) 基于Intent对应的 Intent.FilterComparison 从ServiceRecord中获取IntentBindRecord对象。
#3.调用b.binder = service 将Service的aidl服务实现类 对象赋值给binder。即将服务发布绑定到 ServiceRecord.bindings中IntentBindRecord.binder中。
调用 b.requested = true 设置service已绑定。b.received = true 设置
#4.从ServiceRecord.connections列表ArrayMap遍历其中的ConnectionRecord c,调用c.conn.connected(r.name, service, false) 调用同下5
5.如果service已经启动且绑定过 (s.app != null && b.intent.received),调用c.conn.connected(s.name, b.intent.binder, false),其中c为ConnectionRecord对象。c.conn为缓存的 IServiceConnection aidl 服务端实现类InnerConnection对象。
b.intent 为 AppBindRecord.intent,即IntentBindRecord 为封装了service的Intent的Intent.FilterComparison对象的IntentBindRecord对象.
即通过aidl 跨进程调用 IServiceConnection aidl 服务端实现类InnerConnection.connected方法
Service客户端进程:
LoadedApk.ServiceDispatcher.InnerConnection.connected(ComponentName name, IBinder service, boolean dead) 调用sd.connected(name, service, dead),
其中sd为应用调用bindService时创建的ServiceDispatcher对象,
LoadedApk.ServiceDispatcher.connected(ComponentName name, IBinder service, boolean dead) 调用doConnected(name, service, dead),
LoadedApk.ServiceDispatcher.doConnected(ComponentName name, IBinder service, boolean dead) 该方法先掉info = new ConnectionInfo()创建 LoadedApk.ServiceDispatcher.ConnectionInfo对象
然后调用info.binder = service 将Service的aidl服务实现类 对象赋值给binder。
调用 mConnection.onServiceConnected(name, service) 调用客户端的ServiceConnection.onServiceConnected方法
ServiceConnection.onServiceConnected(ComponentName name, IBinder service) service为 客户端获取到Service的aidl服务实现类的binder,即可以通过该binder同service服务端进行aidl 跨进程通信。
四、总结:
1.应用bindService时 会先创建一个LoadedApk.ServiceDispatcher对象和一个LoadedApk.ServiceDispatcher.InnerConnection(继承IServiceConnection.Stub) 是aidl 服务端实现类对象mIServiceConnection,
2.mIServiceConnection会被存储到ams中ActiveServices.ServiceRestarter.mService(ServiceRecord对象).connections 。
3.然后ams通过调用LoadedApk中 aidl 服务端实现类对象mIServiceConnection.connected(r.name, service, false) 方法调用到 Service客户端进程,参数service 为Service的aidl服务实现类的binder。
最终调用Service客户端应用的ServiceConnection.onServiceConnected方法,Service客户端应用拿到service binder后可以和service aidl通信。