SystemService生命周期
SystemService 的生命周期分成三条互补路径:onStart() 让服务进入运行态并发布接口;onBootPhase() 随 SystemServer 阶段推进获取依赖或执行一次性初始化;onUserStarting/onUserUnlocking/onUserUnlocked/onUserSwitching/onUserStopping/onUserStopped 管理 per-user 状态。所有回调由 SystemServiceManager 编排,但服务自己拥有状态、Binder、LocalServices 和用户数据。
1. 基类契约
源码文件:frameworks/base/services/core/java/com/android/server/SystemService.java
public abstract class SystemService {
private final Context mContext;
protected SystemService(@NonNull Context context) {
mContext = context;
}
public final Context getContext() {
return mContext;
}
public abstract void onStart();
public void onBootPhase(@BootPhase int phase) {}
public void onUserStarting(@NonNull TargetUser user) {}
public void onUserUnlocking(@NonNull TargetUser user) {}
public void onUserUnlocked(@NonNull TargetUser user) {}
public void onUserSwitching(
@Nullable TargetUser from, @NonNull TargetUser to) {}
public void onUserStopping(@NonNull TargetUser user) {}
public void onUserStopped(@NonNull TargetUser user) {}
}构造器只保存 system context;onStart() 是唯一抽象方法,服务必须实现;其他生命周期默认空实现,服务按需覆盖。SystemService 基类不自动发布 Binder,也不自动创建线程,避免把所有服务强制绑定到同一资源模型。
2. onStart发布
源码文件:frameworks/base/services/core/java/com/android/server/SystemService.java
protected final void publishBinderService(
@NonNull String name, @NonNull IBinder service) {
publishBinderService(name, service, false);
}
protected final void publishLocalService(
@NonNull Class<?> type, @NonNull Object service) {
LocalServices.addService(type, service);
}服务在 onStart() 中决定跨进程 Binder 名称和进程内 LocalServices 类型。Binder 发布由 ServiceManager 消费,LocalServices 只在 system_server 进程内可见。生命周期管理器只保证 onStart() 被调用,不替服务选择接口。
3. BootPhase分发
源码文件:frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
public void startBootPhase(
@NonNull TimingsTraceAndSlog t, int phase) {
if (phase <= mCurrentPhase) {
throw new IllegalArgumentException(
"Next phase must be larger than previous");
}
mCurrentPhase = phase;
final int serviceLen = mServices.size();
ArrayList<SystemService> serialServices = new ArrayList<>();
ArrayList<SystemService> parallelServices = new ArrayList<>();
for (int i = 0; i < serviceLen; i++) {
SystemService service = mServices.get(i);
if (!Flags.parallelizeOnbootphase()
|| service.getBootPhaseSerial(mCurrentPhase)) {
serialServices.add(service);
} else {
parallelServices.add(service);
}
}phase 严格递增,服务列表快照来自 mServices。flag 关闭时全部串行;开启时,服务通过 getBootPhaseSerial() 声明是否必须串行。串行/并行分类不改变服务注册顺序,只改变回调执行方式。
4. 串行与并行回调
for (SystemService service : serialServices) {
long time = SystemClock.elapsedRealtime();
t.traceBegin("OnBootPhase_" + phase + "_"
+ service.getClass().getName());
try {
service.onBootPhase(mCurrentPhase);
} catch (Exception ex) {
throw new RuntimeException(
"Failed to boot service "
+ service.getClass().getName(), ex);
}
warnIfTooLong(
SystemClock.elapsedRealtime() - time,
service, "onBootPhase");
t.traceEnd();
}
Future<?>[] futures = new Future<?>[parallelServices.size()];
for (int i = 0; i < parallelServices.size(); i++) {
SystemService service = parallelServices.get(i);
futures[i] = SystemServerInitThreadPool.submit(
() -> service.onBootPhase(mCurrentPhase),
"OnBootPhase_" + phase + "_"
+ service.getClass().getName());
}串行回调在当前线程执行并逐项告警;并行回调提交到初始化线程池。后续源码会等待 Future 并传播异常,因此提交成功不等于阶段完成。服务若依赖另一个服务刚在同一 phase 写入的状态,应通过 getBootPhaseSerial() 保持顺序。
5. Battery示例
源码文件:frameworks/base/services/core/java/com/android/server/BatteryService.java
@Override
public void onStart() {
registerHealthCallback();
mBinderService = new BinderService();
publishBinderService("battery", mBinderService);
mBatteryPropertiesRegistrar =
new BatteryPropertiesRegistrar();
publishBinderService(
"batteryproperties", mBatteryPropertiesRegistrar);
publishLocalService(
BatteryManagerInternal.class, new LocalService());
}
@Override
public void onBootPhase(int phase) {
if (phase == PHASE_ACTIVITY_MANAGER_READY) {
// 注册低电量设置观察者并更新 warning level。
}
}Battery 的 onStart() 同时建立 health HAL callback、两个 Binder 服务和一个 LocalServices 接口;onBootPhase() 等 AMS ready 后才访问 Settings/注册观察者。服务接口已发布不等于所有配置监听器已建立。
6. 用户生命周期
源码文件:frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
public void onUserStarting(
@NonNull TimingsTraceAndSlog t, int userId) {
TargetUser targetUser = newTargetUser(userId);
synchronized (mTargetUsers) {
if (userId == UserHandle.USER_SYSTEM
&& mTargetUsers.contains(userId)) {
Slog.e(TAG, "Skipping starting system user twice");
return;
}
mTargetUsers.put(userId, targetUser);
}
onUser(t, USER_STARTING, null, targetUser);
}
public void onUserStopped(int userId) {
onUser(USER_STOPPED, userId);
synchronized (mTargetUsers) {
mTargetUsers.remove(userId);
}
}TargetUser 是 manager 的用户状态 owner;启动时先放入 map,再向服务广播;停止时先通知服务清理,完成后才移除 map。System user 在 Automotive/Headless 模式可能收到重复启动事件,源码用 map 去重。
7. 回调线程
基类注释规定生命周期方法由 SystemServer 主 Looper 线程调用;User lifecycle 在 SystemServiceManager 中可按 flag 使用用户线程池,但服务必须按 callback 合同保护自己的 per-user 状态。isUserSupported(TargetUser) 默认 true,服务可以覆盖以跳过 headless/system user 等不支持的用户。
8. 失败定位与导航
onStart()失败:查服务构造后的 Binder/Local 发布和内部线程;onBootPhase()失败:查 phase 单调性、串行声明和 Future 异常;- 用户启动重复:查
mTargetUsers与 Headless System User 条件; - 用户停止后残留:检查服务是否在
onUserStopped()完成资源解绑后才释放 per-user map; - Binder 可查但功能未就绪:区分 onStart 发布与 onBootPhase 配置完成。
# 输入基类,输出生命周期和发布辅助方法。
rg -n "abstract class SystemService|onStart\(|onBootPhase\(|onUserStarting|onUserUnlocked|onUserSwitching|onUserStopping|onUserStopped|publishBinderService|publishLocalService" \
frameworks/base/services/core/java/com/android/server/SystemService.java
# 输入管理器,输出 phase 分发、用户状态 map、串并行和 Future。
rg -n "startBootPhase|parallelizeOnbootphase|getBootPhaseSerial|onUserStarting|mTargetUsers|onUserStopped|SystemServerInitThreadPool" \
frameworks/base/services/core/java/com/android/server/SystemServiceManager.java下一篇将专门整理 BootPhase 常量与实际调用点,解释 PHASE_WAIT_FOR_DEFAULT_DISPLAY、PHASE_ACTIVITY_MANAGER_READY 等阶段由谁推进、哪些服务消费;不会重复本文的基类回调实现。
