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
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
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. 启动计数
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. 进程级默认策略
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. 主线程与线程池
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前置
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()。
# 入口、构造、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 和初始化线程池。
