一、SystemServer的启动
从上文得知,SystemServer的启动源头,在于Zygote进程在fork新进程后,执行了SystemServer的main方法。
platform/frameworks/base/services/java/com/android/server/SystemServer.java
public static void main(String[] args) {
new SystemServer().run();
}
首先,看下SystemServer构造方法:
public SystemServer() {
// Record process start information.
mStartCount = SystemProperties.getInt(SYSPROP_START_COUNT, 0) + 1;
mRuntimeStartElapsedTime = SystemClock.elapsedRealtime();
mRuntimeStartUptime = SystemClock.uptimeMillis();
Process.setStartTimes(mRuntimeStartElapsedTime, mRuntimeStartUptime, mRuntimeStartElapsedTime, mRuntimeStartUptime);
// Remember if it's runtime restart or reboot.
mRuntimeRestart = mStartCount > 1;
}
分别从elapsedRealtime和uptimeMillis两个方式记录了SystemServer的启动时间,保存在了Process中,同时记录了启动次数mStartCount。
继续看run方法:
private void run() {
// 在System Propertie中记录启动时间
SystemProperties.set(SYSPROP_START_COUNT, String.valueOf(mStartCount));
SystemProperties.set(SYSPROP_START_ELAPSED, String.valueOf(mRuntimeStartElapsedTime));
SystemProperties.set(SYSPROP_START_UPTIME, String.valueOf(mRuntimeStartUptime));
// SystemServer中只能发送oneway的binder请求
Binder.setWarnOnBlocking(true);
// SYNC_MODE_FULL模式确保每次数据库再进一步操作前,所有数据已保存到磁盘
SQLiteGlobal.sDefaultSyncMode = SQLiteGlobal.SYNC_MODE_FULL;
...
// 临时取消虚拟机GrowthLimit,这样在SystemServer启动过程中不会频繁触发GC,降低启动效率
VMRuntime.getRuntime().clearGrowthLimit();
// 收集下参数后设置"ro.build.fingerprint"值到SystemProperties
Build.ensureFingerprintProperty();
// 没有明确指定一个用户的前提下,SystemServer内部不可以访问Environment相关的path目录
Environment.setUserRequired(true);
// SystemServer内部拒绝呼入(incoming)的Bundles
BaseBundle.setShouldDefuse(true);
...
//
// 重新设置SystemServer的Binder Thread数(31个)
BinderInternal.setMaxThreads(sMaxBinderThreads);
// 设置线程优先级(-2)
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_FOREGROUND);
// 如果在本进程内将线程优先级设置低于ANDROID_PRIORITY_BACKGROUND(值>10)则抛出异常
android.os.Process.setCanSelfBackground(false);
Looper.prepareMainLooper();
Looper.getMainLooper().setSlowLogThresholdMs(
SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);
...
// 加载native的SystemServer
System.loadLibrary("android_servers");
// 打开heapprofd性能分析数据采集(debug模式下)
initZygoteChildHeapProfiling();
// 创建一个线程,定期检查fd数量。超过阈值则启用fdtrack
if (Build.IS_DEBUGGABLE) {
spawnFdLeakCheckThread();
}
// 如果上次shutdown失败,重新尝试shutdown
performPendingShutdown();
// 创建上下文
createSystemContext();
// 初始化各种主线模块 ActivityThread.initializeMainlineModules();
// 创建SystemServiceManager
mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setStartInfo(mRuntimeRestart, mRuntimeStartElapsedTime, mRuntimeStartUptime);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
SystemServerInitThreadPool tp = SystemServerInitThreadPool.start();
...
// Start services.
try {
t.traceBegin("StartServices");
// 启动关键引导服务 AMS、PMS等
startBootstrapServices(t);
// 启动基础服务 BatteryService等
startCoreServices(t);
// 其他一些服务
startOtherServices(t);
startApexServices(t);
// Only update the timeout after starting all the services so that we use
// the default timeout to start system server.
updateWatchdogTimeout(t);
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
t.traceEnd(); // StartServices
}
...
// 初始化严苛模式
StrictMode.initVmDefaults(null);
Looper.loop();
}
从run方法中,我们看到SystemServer的启动主要做了以下工作:
- 进行启动时间、日志、heapprofd、严苛模式等性能采集相关的基本设置,以及进程优先级、binder、虚拟机内存等保障SystemServer正常运行的基本设置。
- 创建SystemContext上下文
- 创建SystemServiceManager,通过startBootstrapServices(关键引导服务)、startCoreServices(核心服务)、startOtherServices(其他各路混杂的服务)、startApexServices等启动各类服务
- 启动looper。
二、服务管理
在startBootstrapServices、startCoreServices、startOtherServices、startApexServices中,对各类服务进行了启动,比如我们常见的ActivityManagerService、PackageManagerService、BatteryService等等,共近百个Service。而对Service启动的方式是相似的,以startBootstrapServices为例:
private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {
...
final Watchdog watchdog = Watchdog.getInstance();
watchdog.start();
SystemServerInitThreadPool.submit(SystemConfig::getInstance, TAG_SYSTEM_CONFIG);
PlatformCompat platformCompat = new PlatformCompat(mSystemContext);
ServiceManager.addService(Context.PLATFORM_COMPAT_SERVICE, platformCompat);
ServiceManager.addService(Context.PLATFORM_COMPAT_NATIVE_SERVICE,
new PlatformCompatNative(platformCompat));
...
Installer installer = mSystemServiceManager.startService(Installer.class);
...
ActivityTaskManagerService atm = mSystemServiceManager.startService(ActivityTaskManagerService.Lifecycle.class).getService();
mActivityManagerService = ActivityManagerService.Lifecycle.startService(mSystemServiceManager, atm);
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
...
mSystemServiceManager.startBootPhase(t, SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
...
}
而在startOtherServices中,对有这样一些处理:
private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
...
ServiceManager.addService("scheduling_policy", new SchedulingPolicyService());
mSystemServiceManager.startService(ACCOUNT_SERVICE_CLASS);
wm = Window
new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);
ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
mActivityManagerService.setWindowManager(wm);
...
mSystemServiceManager.startServiceFromJar(
WIFI_SERVICE_CLASS, WIFI_APEX_SERVICE_JAR_PATH);
...
}
startOtherServices里处理的服务要比其他三个方法里庞杂的多,但综上,SystemServer对服务的管理主要有以下方式:
- mSystemServiceManager.startService -- 启动一个服务
- mSystemServiceManager.startBootPhase -- 广播所有已启动的服务当前的启动阶段
- ServiceManager.addService -- 将服务纳入ServiceManager进行管理
ServiceManager是一个handler为0的binder service,将服务addServer(key, service)到ServiceManager后,可以通过key轻松获取对应服务。所有SystemServer启动的Service都被加入到了ServiceManager中。因此后续直接通过key获取到对应Service的binder服务端
SystemServiceManager是SystemServer在本地集中启动、管理各Service的管理类,所有Service必须继承SystemService
看下SystemService的接口:
platform/frameworks/base/services/core/java/com/android/server/SystemService.java
public abstract class SystemService {
...
public abstract void onStart();
public void onBootPhase(@BootPhase int phase) {}
...
}
看下SystemServiceManager的startService:
SystemServiceManager(Context context) {
mContext = context;
mServices = new ArrayList<>();
mServiceClassnames = new ArraySet<>();
mNumUserPoolThreads = Math.min(Runtime.getRuntime().availableProcessors(),
DEFAULT_MAX_USER_POOL_THREADS);
}
public <T extends SystemService> T startService(Class<T> serviceClass) {
if (!SystemService.class.isAssignableFrom(serviceClass)) {
throw new RuntimeException("Failed to create " + name
+ ": service must extend " + SystemService.class.getName());
try {
Constructor<T> constructor = serviceClass.getConstructor(Context.class);
service = constructor.newInstance(mContext);
}
...
startService(service);
}
}
public void startService(@NonNull final 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);
// Register it.
mServices.add(service);
// Start it.
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");
}
startService的过程就是通过Class去反射构建Service对象。然后调用其onStart方法。
在此过程中,使用mServiceClassnames和mServices两个集合去缓存Service相关信息。mServiceClassnames用于避免重复启动;mServices用于存储所有service,在相应时候集中处理,比如startBootPhase方法广播所有service当前进入的启动阶段:
public void startBootPhase(@NonNull TimingsTraceAndSlog t, int phase) {
if (phase <= mCurrentPhase) {
throw new IllegalArgumentException("Next phase must be larger than previous");
}
mCurrentPhase = phase;
Slog.i(TAG, "Starting phase " + mCurrentPhase);
try {
t.traceBegin("OnBootPhase_" + phase);
final int serviceLen = mServices.size();
for (int i = 0; i < serviceLen; i++) {
final SystemService service = mServices.get(i);
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()
+ ": onBootPhase threw an exception during phase "
+ mCurrentPhase, ex);
}
warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onBootPhase");
t.traceEnd();
}
} finally {
t.traceEnd();
}
if (phase == SystemService.PHASE_BOOT_COMPLETED) {
final long totalBootTime = SystemClock.uptimeMillis() - mRuntimeStartUptime;
t.logDuration("TotalBootTime", totalBootTime);
SystemServerInitThreadPool.shutdown();
}
}
所有的service的onBootPhase会被调用。
对于startBootPhase的使用场景,举个例子:
在系统启动动画播放完成后,ActivityManagerService会在finishBooting中调用startBootPhase,通知所有其他service当前进入了这个PHASE_BOOT_COMPLETED状态
platform/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
final void finishBooting() {
...
// Let system services know.
mSystemServiceManager.startBootPhase(t, SystemService.PHASE_BOOT_COMPLETED);
...
}
而如果你想监听PHASE_BOOT_COMPLETED这个阶段,则可以在onBootPhase中判断接收到的phase,比如:
platform/frameworks/base/services/core/java/com/android/server/StorageManagerService.java
public void onBootPhase(int phase) {
if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
mStorageManagerService.servicesReady();
} else if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
mStorageManagerService.systemReady();
} else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
mStorageManagerService.bootCompleted();
}
}
startBootPhase -> onBootPhase的设计,是对Service之间、以及Service对系统各阶段依赖性的一个处理。在启动过程中各阶段的优化工作上是一个切入点。
使用一个并不严谨的图大致表现下各角色的关系: