当前位置: 首页 > article >正文

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通信。
 


http://www.kler.cn/a/546972.html

相关文章:

  • 主动视觉可能就是你所需要的:在双臂机器人操作中探索主动视觉
  • 【css】width:100%;padding:20px;造成超出100%宽度的解决办法 - box-sizing的使用方法 - CSS布局
  • 一种 SQL Server 数据库恢复方案:解密、恢复并导出 MDF/NDF/BAK文件
  • 【ArcGIS Pro二次开发】(87):样式_Style的用法
  • 云计算实训室解决方案(2025年最新版)
  • Chrome 浏览器可以读写本地文件了,虽说是实验api,但是基本86+已经支持了
  • AlmaLinux9.5安装samba实现与Windows文件共享 笔记250214
  • 基于SpringBoot的电影院售票管理系统
  • 基于 openEuler 构建 LVS-NAT 集群和ldirectord监控RS
  • IOTDB安装部署
  • 19.4.2 -19.4.4 新增、修改、删除数据
  • MySQL的SQL执行流程
  • 机器学习 - 理论和定理
  • Java进阶,时间与日期,包装类,正则表达式
  • RedHat8安装postgresql15和 postgis3.4.4记录及遇到的问题总结
  • deepseek部署在本地详细教程
  • 木材表面缺陷检测数据集,支持YOLO+COCO JSON+PASICAL VOC XML+DARKNET格式标注信息,平均正确识别率95.0%
  • 【开发工具】开发一个类postman的idea插件
  • 工业路由器物联网应用,智慧环保环境数据监测
  • 【Linux】ip命令详解