Skip to content

SystemServiceManager

深入 SystemServiceManager 的三种启动入口、反射构造、去重列表、onStart、服务封口与 BootPhase 分发。

基于android-17.0.0_r1
AndroidSystemServerSystemServiceManager源码阅读

SystemServiceManager ​

SystemServiceManager 管理的是 SystemServer 进程内的 SystemService 实例和生命周期,不是 servicemanager 的 Binder 名称表。它接收 class、class name、standalone jar 或现成实例,统一执行反射构造、类名去重、加入 mServices、调用 onStart(),并在后续 boot phase 中遍历同一列表调用 onBootPhase()。

1. 状态owner ​

源码文件:frameworks/base/services/core/java/com/android/server/SystemServiceManager.java

java
public SystemServiceManager(Context context) {
    mContext = context;
    mServices = new ArrayList<>();
    mServiceClassnames = new ArraySet<>();
    mNumUserPoolThreads = Math.min(
            Runtime.getRuntime().availableProcessors(),
            DEFAULT_MAX_USER_POOL_THREADS);
}

mContext 是 SS018 创建的 system context;mServices 保存已经登记的实例并成为 boot/user lifecycle 遍历源;mServiceClassnames 防止同一个类重复启动。user lifecycle 线程数按 CPU 数和上限取最小值,与普通服务 onStart() 不共用线程池。

2. 三种类型入口 ​

java
public SystemService startService(String className) {
    Class<SystemService> serviceClass = loadClassFromLoader(
            className, this.getClass().getClassLoader());
    return startService(serviceClass);
}

public SystemService startServiceFromJar(
        String className, String path) {
    PathClassLoader loader =
            SystemServerClassLoaderFactory.getOrCreateClassLoader(
                    path, this.getClass().getClassLoader(),
                    isJarInTestApex(path));
    Class<SystemService> serviceClass =
            loadClassFromLoader(className, loader);
    return startService(serviceClass);
}

String 入口使用当前 SystemServer classloader,适合运行时 classpath 中但编译期无法直接引用的类;jar 入口建立/复用 PathClassLoader,适合 standalone SystemServer jar/APEX jar;显式 Class<T> 入口类型最安全。三者最终都进入 startService(Class)。

3. 反射构造约束 ​

java
public <T extends SystemService> T startService(
        Class<T> serviceClass) {
    try {
        String name = serviceClass.getName();
        Trace.traceBegin(
                Trace.TRACE_TAG_SYSTEM_SERVER,
                "StartService " + name);

        if (!SystemService.class.isAssignableFrom(serviceClass)) {
            throw new RuntimeException(
                    "service must extend SystemService");
        }

        Constructor<T> constructor =
                serviceClass.getConstructor(Context.class);
        T service = constructor.newInstance(mContext);
        startService(service);
        return service;
    } finally {
        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
    }
}

服务类必须继承 SystemService,并拥有 public Constructor(Context)。无法实例化、构造器不可访问、缺少构造器或构造器内部异常分别包装为不同 RuntimeException。trace finally 保证失败也结束 StartService <class> 区间。

4. 登记与onStart ​

java
public void startService(@NonNull SystemService service) {
    String className = service.getClass().getName();
    if (mServiceClassnames.contains(className)) {
        Slog.i(TAG,
                "Not starting an already started service "
                + className);
        return;
    }
    mServiceClassnames.add(className);
    mServices.add(service);

    long time = SystemClock.elapsedRealtime();
    try {
        service.onStart();
    } catch (RuntimeException ex) {
        throw new RuntimeException(
                "Failed to start service "
                + service.getClass().getName()
                + ": onStart threw an exception", ex);
    }
    warnIfTooLong(
            SystemClock.elapsedRealtime() - time,
            service, "onStart");
}

源码先加入 class name 和实例列表,再调用 onStart()。因此 onStart() 抛异常时实例已经存在于 mServices,但外层 SystemServer 启动通常会终止,不会把该半启动状态当作可继续服务。重复类名只记录并返回,传入的新实例不会执行 onStart()。

onStart() 的职责通常是发布 Binder/LocalServices、注册监听或启动内部线程;具体行为属于服务实现。SystemServiceManager 只负责调用时机和耗时告警。

5. 加载失败 ​

java
private static Class<SystemService> loadClassFromLoader(
        String className, ClassLoader classLoader) {
    try {
        return (Class<SystemService>) Class.forName(
                className, true, classLoader);
    } catch (ClassNotFoundException ex) {
        throw new RuntimeException(
                "Failed to create service " + className
                + " from class loader " + classLoader
                + ": service class not found...", ex);
    }
}

Class.forName(..., true, loader) 会执行静态初始化。错误文本提示调用者先检查 PackageManager.hasSystemFeature() 和 jar path,这说明“类不存在”经常是条件分支或 classloader 配置错误,而不是 SystemServiceManager 自身状态损坏。

6. 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;
    t.traceBegin("OnBootPhase_" + phase);
    ...
}

phase 必须严格递增;mCurrentPhase 是进程级阶段 owner。重复或倒退会在遍历服务前抛异常,避免某些服务收到重复/乱序生命周期回调。

7. 串行与并行回调 ​

java
for (SystemService service : mServices) {
    if (!Flags.parallelizeOnbootphase()
            || service.getBootPhaseSerial(mCurrentPhase)) {
        serialServices.add(service);
    } else {
        parallelServices.add(service);
    }
}

for (SystemService service : serialServices) {
    service.onBootPhase(mCurrentPhase);
    warnIfTooLong(..., service, "onBootPhase");
}

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());
}

是否允许并行由全局 flag 和服务的 getBootPhaseSerial(phase) 共同决定。串行服务在调用线程执行;并行服务提交到 SystemServerInitThreadPool,随后方法必须等待 Future 并传播异常,不能把“已提交”写成 phase 已完成。

8. 服务封口 ​

源码文件:frameworks/base/services/core/java/com/android/server/SystemServiceManager.java

java
public void sealStartedServices() {
    mServiceClassnames = Collections.emptySet();
    mServices = Collections.unmodifiableList(mServices);
}

封口发生在 Apex 服务组之后。已有服务仍接受 boot/user lifecycle 回调,但列表不能再新增;这是平台与可更新 APEX 依赖边界。封口不是清空服务,mServices 只是转为不可修改视图。

9. 失败定位与导航 ​

  • class not found:检查 feature gate、classpath 和 jar path;
  • 构造失败:检查是否继承 SystemService、public Context 构造器和静态初始化;
  • onStart() 失败:回到具体服务发布/线程/监听器逻辑;
  • boot phase 乱序:检查调用者 phase 顺序;
  • 并行回调失败:检查 Future 异常,不只看提交日志;
  • 重复服务:检查相同 class 是否由两个启动分支触发。
bash
# 启动入口、反射、去重、onStart 和封口。
rg -n "startService\(|startServiceFromJar|loadClassFromLoader|mServiceClassnames|mServices|onStart|sealStartedServices" \
  frameworks/base/services/core/java/com/android/server/SystemServiceManager.java

# Boot phase 单调性、串并行分类和 Future 等待。
rg -n "startBootPhase|mCurrentPhase|getBootPhaseSerial|parallelServices|SystemServerInitThreadPool|onBootPhase|warnIfTooLong" \
  frameworks/base/services/core/java/com/android/server/SystemServiceManager.java

下一篇将进入 SystemService 基类生命周期,解释 onStart/onBootPhase/onUser* 和 publishBinderService/publishLocalService;不会重复本文的反射和列表管理。