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中。

  1. 从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

  1. 先从 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通信。

相关推荐
openinstall全渠道统计3 小时前
免填邀请码工具:赋能六大核心场景,重构App增长新模型
android·ios·harmonyos
双鱼大猫3 小时前
一句话说透Android里面的ServiceManager的注册服务
android
双鱼大猫3 小时前
一句话说透Android里面的查找服务
android
双鱼大猫3 小时前
一句话说透Android里面的SystemServer进程的作用
android
双鱼大猫3 小时前
一句话说透Android里面的View的绘制流程和实现原理
android
双鱼大猫4 小时前
一句话说透Android里面的Window的内部机制
android
双鱼大猫5 小时前
一句话说透Android里面的为什么要设计Window?
android
双鱼大猫5 小时前
一句话说透Android里面的主线程创建时机,frameworks层面分析
android
苏金标5 小时前
android 快速定位当前页面
android
雾里看山8 小时前
【MySQL】内置函数
android·数据库·mysql