Skip to content

SystemServer.main

拆解 SystemServer.main、构造函数、启动计数、runtime restart 和 run() 的进程级初始化边界。

基于android-17.0.0_r1
AndroidSystemServerZygote源码阅读

SystemServer.main ​

SystemServer.main() 很短,但它承担的不是“调用一个普通 Java main”。它创建 SystemServer 对象,在构造函数中记录启动次数、uptime 和 runtime restart 状态,然后进入 run();run() 再建立 Perfetto、系统属性、时区、Binder 线程配置、主 Looper、初始化线程池和 system context,最后才进入服务组启动。本文只讲进程级入口和 run() 前半段,具体 Bootstrap/Core/Other/Apex 服务留给后续文章。

1. 静态入口与构造 ​

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

java
public static void main(String[] args) {
    new SystemServer().run();
}

public SystemServer() {
    mFactoryTestMode = FactoryTest.getMode();
    mStartCount = SystemProperties.getInt(
            SYSPROP_START_COUNT, 0) + 1;
    mRuntimeStartElapsedTime =
            SystemClock.elapsedRealtime();
    mRuntimeStartUptime = SystemClock.uptimeMillis();
    Process.setStartTimes(
            mRuntimeStartElapsedTime,
            mRuntimeStartUptime,
            mRuntimeStartElapsedTime,
            mRuntimeStartUptime);
    mRuntimeRestart = mStartCount > 1;
}

main() 不消费参数,也不在这里创建 Looper。构造函数的 owner 是当前 SystemServer 进程:从系统属性读取并递增启动计数,记录 elapsed/uptime 两种时钟,再把 mRuntimeRestart 定义为启动次数大于 1。runtime restart 与整机 reboot 的差异从这里进入后续服务编排。

2. run入口 ​

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

java
private void run() {
    if (VMDebug.isDebuggingEnabled()
            && SystemProperties.getBoolean(
                    "debug.system_server.jdwp_wait", false)) {
        Slog.i(TAG, "System server is waiting for debugger before starting...");
        Debug.waitForDebugger();
    }

    TimingsTraceAndSlog t = new TimingsTraceAndSlog();
    try {
        android.tracing.perfetto.Producer.init(
                new InitArguments(
                    InitArguments.PERFETTO_BACKEND_SYSTEM,
                    4 * 1024));
        t.traceBegin("InitBeforeStartServices");

debugger 等待发生在所有服务启动前,并且必须同时满足 VM debugging 和属性开关;生产系统不会因为普通启动自动阻塞。Perfetto producer 先初始化 4 MB shared memory buffer,随后 TimingsTraceAndSlog 记录启动阶段,成为后续服务耗时分析的时间线 owner。

3. 启动计数 ​

java
SystemProperties.set(SYSPROP_START_COUNT,
        String.valueOf(mStartCount));
SystemProperties.set(SYSPROP_START_ELAPSED,
        String.valueOf(mRuntimeStartElapsedTime));
SystemProperties.set(SYSPROP_START_UPTIME,
        String.valueOf(mRuntimeStartUptime));

EventLog.writeEvent(EventLogTags.SYSTEM_SERVER_START,
        mStartCount,
        mRuntimeStartUptime,
        mRuntimeStartElapsedTime);

SystemTimeZone.initializeTimeZoneSettingsIfRequired();

属性写回让后续进程和崩溃恢复逻辑看到本次启动编号;EventLog 是启动诊断消费者,时间同时保留 uptime 与 elapsed。时区初始化在服务组之前执行,避免服务构造阶段读取未完成的系统时区状态。

4. 进程级默认策略 ​

java
Binder.setWarnOnBlocking(true);
PackageItemInfo.forceSafeLabels();
SQLiteGlobal.sDefaultSyncMode = SQLiteGlobal.SYNC_MODE_FULL;
SQLiteCompatibilityWalFlags.init(null);

VMRuntime.getRuntime().clearGrowthLimit();
Build.ensureFingerprintProperty();
Environment.setUserRequired(true);
BaseBundle.setShouldDefuse(true);
Parcel.setStackTraceParceling(true);
BinderInternal.disableBackgroundScheduling(true);
BinderInternal.setMaxThreads(sMaxBinderThreads);

这些调用在服务启动前建立 SystemServer 进程级默认值:Binder 同步调用阻塞会告警,资源标签强制安全显示,SQLite 默认 FULL,同一进程中的 Environment 路径要求显式 user,Bundle 默认 defuse,Parcel 异常携带 stack trace,Binder 调度关闭后台降级并提高线程上限。它们不是某个服务的局部配置,服务启动后会继承这些默认策略。

5. 主线程与线程池 ​

java
Process.setThreadPriority(
        Process.THREAD_PRIORITY_FOREGROUND);
MessageQueue.setUseDeliQueue(true);
Looper.prepareMainLooper();
Looper.getMainLooper().setSlowLogThresholdMs(
        SLOW_DISPATCH_THRESHOLD_MS,
        SLOW_DELIVERY_THRESHOLD_MS);

SystemServerInitThreadPool.start();
mDumper.addDumpable(
        SystemServerInitThreadPool.getInstance());

startSystemConfigInit(t);
System.loadLibrary("android_servers");

主线程先提升到 foreground,再创建主 Looper 并配置慢 dispatch/delivery 日志;SystemServerInitThreadPool 用于并行化可提前执行的初始化。startSystemConfigInit(t) 把昂贵的 SystemConfig.getInstance() 提交给线程池,服务组启动时再通过 Future 等待结果。android_servers native 库加载是 SystemServer 后续 JNI 服务的前置依赖。

6. Context前置 ​

java
ApplicationSharedMemory instance =
        ApplicationSharedMemory.create();
ApplicationSharedMemory.setInstance(instance);

createSystemContext();
ActivityThread.initializeMainlineModules();

ServiceManager.addService("system_server_dumper", mDumper);
mDumper.addDumpable(this);

mSystemServiceManager =
        new SystemServiceManager(mSystemContext);
mSystemServiceManager.setStartInfo(
        mRuntimeRestart,
        mRuntimeStartElapsedTime,
        mRuntimeStartUptime);
LocalServices.addService(
        SystemServiceManager.class, mSystemServiceManager);

SystemServer 在真正启动服务组前先创建 ApplicationSharedMemory、system context、mainline modules 和 dumper Binder 服务,再创建 SystemServiceManager 并同时写入 LocalServices。这个阶段同时建立跨进程调试入口(ServiceManager)和进程内编排入口(LocalServices),不能把两张表混为一张服务注册表。

7. 失败定位 ​

run() 前半段的失败 owner 可以按层定位:Perfetto/属性/EventLog 是启动观测层;Binder/Parcel/Bundle/Environment 是进程默认策略层;Looper/InitThreadPool 是执行调度层;android_servers 和 SystemContext 是 native/framework 接缝层。任何一层抛出异常都会阻止后续服务组进入 startBootstrapServices()。

bash
# 入口、构造、restart 计数和 run 前半段
rg -n "public static void main|public SystemServer|mStartCount|mRuntimeRestart|private void run" \
  frameworks/base/services/java/com/android/server/SystemServer.java

# Binder/Parcel/Bundle/Looper/线程池默认策略
rg -n "setWarnOnBlocking|setShouldDefuse|setStackTraceParceling|setMaxThreads|prepareMainLooper|SystemServerInitThreadPool" \
  frameworks/base/services/java/com/android/server/SystemServer.java

# context、dumper、SystemServiceManager 和 LocalServices
rg -n "ApplicationSharedMemory|createSystemContext|system_server_dumper|SystemServiceManager|LocalServices" \
  frameworks/base/services/java/com/android/server/SystemServer.java

下一篇将展开 SystemServer.run() 调用四组 start*Services() 的服务编排顺序;不会重复本文的构造状态、主 Looper 和初始化线程池。