
Service启动与绑定
Service作为Android四大组件之一,是运行在后台的服务型组件,承担着非UI交互的后台任务处理、跨进程通信(IPC)等核心职责。
其生命周期管理(启动式、绑定式)由Framework层的ActivityManagerService(AMS) 主导,结合Binder跨进程通信机制实现应用进程与系统服务进程的协同。
本文基于Android 10(API 29) 源码,深度解析Service启动(startService)与绑定(bindService)的Framework层执行流程,揭示其底层实现逻辑。
Service核心概述与关键角色
1 Service的两种核心类型
- 启动式Service :通过
startService()触发,生命周期为onCreate() → onStartCommand()(可多次调用) → onDestroy(),独立于调用者生命周期,即使调用者销毁,Service仍可后台运行。 - 绑定式Service :通过
bindService()触发,生命周期为onCreate() → onBind() → onUnbind() → onDestroy(),与调用者(客户端)形成强关联,支持IPC通信,无客户端绑定时Service会被销毁。
2 Framework层关键类与角色
- ActivityManagerService(AMS):SystemServer进程中的核心系统服务,负责所有四大组件的生命周期管理、进程调度与权限校验,是Service管理的"总控中心"。
- ActivityThread:应用进程的主线程管理类,处理AMS下发的指令(如创建Service、执行生命周期方法),维护应用进程的组件状态。
- ApplicationThread :ActivityThread的内部类,实现
IApplicationThread接口,作为应用进程与AMS的跨进程通信(Binder)代理,承接AMS的远程调用。 - ServiceRecord:AMS中用于记录Service信息的对象,包含Service的组件名、Intent、进程信息、绑定状态等,是AMS管理Service的核心数据结构。
- ContextImpl :Context的实际实现类,应用层调用的
startService()/bindService()最终由ContextImpl转发至AMS。 - ActivityManagerProxy(AMP):AMS的Binder代理类,应用进程通过AMP与AMS进行跨进程通信。
StartService的Framework层源码解析
启动式Service的核心流程是应用进程→AMS(跨进程)→应用进程(创建Service并执行生命周期),以下为分步解析:
1 应用层调用入口:ContextImpl.startServiceCommon
应用层调用Context.startService(Intent)时,实际执行的是ContextImpl的startServiceCommon方法(封装了通用逻辑,包括权限校验、Intent解析等):
java
// ContextImpl.java (Android 10)
private ComponentName startServiceCommon(Intent service, boolean requireForeground, UserHandle user) {
try {
// 1. 解析Intent,处理权限与用户信息
validateServiceIntent(service);
service.prepareToLeaveProcess(this);
// 2. 获取AMS的代理(AMP),跨进程调用AMS.startService
ComponentName cn = ActivityManager.getService().startService(
mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(getContentResolver()),
requireForeground, getOpPackageName(), user.getIdentifier());
// 3. 处理返回结果(如Service不存在则抛异常)
if (cn != null) {
if (cn.getPackageName().equals("!")) {
throw new SecurityException(...);
} else if (cn.getPackageName().equals("!!")) {
throw new IllegalStateException(...);
}
}
return cn;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
其中ActivityManager.getService()获取的是IActivityManager类型的AMS代理(AMP),通过Binder完成跨进程通信。
2 AMS的startService与ServiceRecord创建
AMS的startService方法最终调用startServiceLocked,核心逻辑为:
- 校验与查找ServiceRecord :根据Intent解析出的组件名,查找AMS中已存在的
ServiceRecord,若不存在则新建(记录Service的核心信息)。 - 调用startServiceInnerLocked :进一步封装Service启动的核心逻辑,最终调用
bringUpServiceLocked。
3 进程创建与Service启动:bringUpServiceLocked
bringUpServiceLocked是Service启动的核心方法,负责检查Service所在进程是否存在,并触发进程创建或Service实例化:
java
// ActivityManagerService.java (Android 10)
private final boolean bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg, boolean whileRestarting) {
// 1. 检查Service所在进程(appProcess)是否存在
ProcessRecord app = mProcessList.getProcessRecordLocked(r.processName, r.appInfo.uid, false);
if (app == null) {
// 2. 进程不存在:通过ZygoteProcess孵化新进程(SystemServer通过Zygote创建应用进程)
app = mProcessList.startProcessLocked(...);
if (app == null) {
return false;
}
}
// 3. 进程存在:调用realStartServiceLocked,实际启动Service
if (app.thread != null) {
realStartServiceLocked(r, app, execInFg);
return true;
}
// 进程未就绪(如正在创建),等待后续处理
return false;
}
- 若Service所在进程未创建,AMS通过
ProcessList.startProcessLocked调用ZygoteProcess的forkAndSpecialize方法,由Zygote孵化新的应用进程,并初始化ActivityThread主线程。 - 进程创建完成后,
app.thread(即应用进程的ApplicationThread代理)变为可用,触发realStartServiceLocked。
4 应用进程的Service实例化:realStartServiceLocked与ActivityThread处理
AMS的realStartServiceLocked通过ApplicationThread的代理(跨进程)调用scheduleCreateService:
java
// ActivityManagerService.java (Android 10)
private final void realStartServiceLocked(ServiceRecord r, ProcessRecord app, boolean execInFg) {
try {
// 1. 跨进程调用应用进程的ApplicationThread.scheduleCreateService
app.thread.scheduleCreateService(r, r.serviceInfo, ...);
// 2. 记录Service启动状态,触发后续的onStartCommand调用
r.postNotification();
// 3. 处理startService的参数,调用scheduleServiceArgs
sendServiceArgsLocked(r, execInFg, true);
} catch (RemoteException e) {
...
}
}
应用进程的ApplicationThread接收到scheduleCreateService后,通过主线程的Handler(H)发送MESSAGE_CREATE_SERVICE消息:
java
// ApplicationThread.java (Android 10)
public final void scheduleCreateService(IBinder token, ServiceInfo info, ...) {
sendMessage(H.CREATE_SERVICE, new CreateServiceData(token, info, ...));
}
ActivityThread的H类处理该消息,调用handleCreateService创建Service实例并执行onCreate():
java
// ActivityThread.java (Android 10)
private void handleCreateService(CreateServiceData data) {
// 1. 加载Service的Class,创建实例
Service service = packageInfo.getAppFactory().instantiateService(...);
// 2. 初始化Service的Context(ServiceContext)
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
service.attach(context, this, data.info.name, data.token, ...);
// 3. 执行Service的onCreate()生命周期方法
service.onCreate();
// 4. 注册Service到ActivityThread的mServices集合中
mServices.put(data.token, service);
}
随后,H处理MESSAGE_SERVICE_ARGS消息,调用handleServiceArgs执行onStartCommand(),完成启动式Service的核心生命周期流程。
BindService的Framework层源码解析
绑定式Service的核心是客户端与Service的IPC通信建立 ,流程比启动式更复杂,涉及ServiceConnection的跨进程管理、IBinder对象的传递等,以下为核心步骤:
1 应用层调用入口:ContextImpl.bindServiceCommon
应用层调用Context.bindService(Intent, ServiceConnection, int)时,执行ContextImpl的bindServiceCommon方法:
java
// ContextImpl.java (Android 10)
private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, UserHandle user) {
// 1. 校验ServiceConnection(必须在主线程)、Intent等
if (conn == null) throw new IllegalArgumentException("connection is null");
// 2. 封装ServiceConnection为LoadedApk.ServiceDispatcher(处理跨进程回调)
LoadedApk.ServiceDispatcher sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), ...);
// 3. 跨进程调用AMS.bindService
return ActivityManager.getService().bindService(
mMainThread.getApplicationThread(), getActivityToken(), service, ..., sd.getIServiceConnection());
}
其中sd.getIServiceConnection()返回IServiceConnection接口的实现类(ServiceDispatcher.InnerConnection),作为AMS与客户端ServiceConnection的通信桥梁。
2 AMS的bindServiceLocked与ConnectionRecord管理
AMS的bindService方法最终调用bindServiceLocked,核心逻辑:
- 创建/复用ServiceRecord :与启动式Service逻辑一致,若Service未注册则新建
ServiceRecord。 - 创建ConnectionRecord :记录客户端与Service的绑定关系(包含
IServiceConnection、绑定标志、客户端进程信息等)。 - 调用bringUpServiceLocked :若Service所在进程未创建,则孵化进程;若已创建,则触发
realStartServiceLocked处理绑定请求。
3 Service的onBind执行与IBinder传递
AMS的realStartServiceLocked中,除了scheduleCreateService(创建Service实例),还会调用scheduleBindService(触发onBind()):
java
// ActivityManagerService.java (Android 10)
private final void realStartServiceLocked(ServiceRecord r, ProcessRecord app, boolean execInFg) {
// ... 省略Service创建逻辑 ...
// 处理绑定请求,跨进程调用scheduleBindService
if (r.hasBindConnections()) {
requestServiceBindingsLocked(r, execInFg);
}
}
private final void requestServiceBindingsLocked(ServiceRecord r, boolean execInFg) {
for (BindRecord br : r.bindings.values()) {
if (!br.requested) {
br.requested = true;
app.thread.scheduleBindService(r, br.intent.getIntent(), execInFg);
}
}
}
应用进程的ApplicationThread接收scheduleBindService后,通过H发送MESSAGE_BIND_SERVICE消息,ActivityThread处理该消息调用handleBindService:
java
// ActivityThread.java (Android 10)
private void handleBindService(BindServiceData data) {
// 1. 获取已创建的Service实例
Service s = mServices.get(data.token);
if (s != null) {
try {
// 2. 执行Service的onBind()方法,返回IBinder对象
IBinder binder = s.onBind(data.intent);
// 3. 跨进程通知AMS,将IBinder传递给客户端
ActivityManager.getService().publishService(data.token, data.intent, binder);
} catch (RemoteException e) {
...
}
}
}
AMS的publishService方法最终调用客户端的IServiceConnection的onServiceConnected,触发应用层ServiceConnection的onServiceConnected回调,完成绑定式Service的IPC通信建立。
4 解绑流程(unbindService)
客户端调用unbindService(ServiceConnection)时,AMS的unbindServiceLocked会移除对应的ConnectionRecord:
- 若Service无任何客户端绑定,则调用
Service的onUnbind(); - 若Service同时未被启动式调用,则进一步调用
onDestroy()销毁Service实例。
关键类的角色总结
| 类名 | 核心角色 |
|---|---|
| ActivityManagerService(AMS) | 系统服务核心,管理ServiceRecord/ConnectionRecord,协调进程创建与Service生命周期 |
| ActivityThread | 应用进程主线程管理类,处理AMS指令,创建Service实例并执行生命周期方法 |
| ApplicationThread | 应用进程与AMS的Binder通信代理,承接AMS的远程调用并转发至ActivityThread |
| ServiceRecord | AMS中Service的元数据载体,记录Service的组件信息、进程信息、绑定状态等 |
| ConnectionRecord | AMS中客户端与Service的绑定关系载体,关联IServiceConnection与ServiceRecord |
| ContextImpl | Context的实际实现类,封装startService/bindService的底层调用逻辑 |
总结
Service的启动与绑定本质是AMS主导的跨进程协同流程,核心依赖Binder机制实现SystemServer进程(AMS)与应用进程的通信,Zygote负责应用进程的孵化,ActivityThread负责Service实例的创建与生命周期执行。理解Framework层源码的意义在于:
- 定位异常问题:如Service启动ANR(AMS超时未收到应用进程响应)、绑定失败(进程权限/Service未注册)等问题的底层根源。
- 适配系统限制:Android 8.0(API 26)后限制后台Service启动,Android 12(API 31)强化前台Service权限,其底层逻辑均体现在AMS的校验规则中。
- 设计高性能IPC :绑定式Service的IBinder通信是Android IPC的核心实现,理解其底层可优化跨进程通信的稳定性与性能。
