Skip to content

SystemService生命周期

追踪 SystemService 的 onStart、onBootPhase、用户生命周期回调、Binder/Local 发布和并行调度。

基于android-17.0.0_r1
AndroidSystemServerSystemService源码阅读

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

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

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

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. 串行与并行回调 ​

java
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

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

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 配置完成。
bash
# 输入基类,输出生命周期和发布辅助方法。
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 等阶段由谁推进、哪些服务消费;不会重复本文的基类回调实现。