安卓启动流程梳理之 System Server进程
安卓系统从开机到桌面显示是一个长而复杂的流程,本文参考安卓源码记录安卓启动流程的梳理学习。(文章涉及的源码基于 Android 10.0)由于 Android 启动流程很长,所以分几篇来记录,本篇记录安卓系统中启动系统众多服务的进程 System Server 的启动流程。
System server
进程进程是安卓系统进入桌面前的最后流程,在 system server
进程启动过程中,启动了系统的众多服务进程。如 AMS
、camera server
等。
System server 启动入口
从前面 zygote
进程启动流程中得知, system server
进程是在 ZygoteInit.java
main()
函数进入循环等待之前启动的。zygote
进程通过 forkSystemServer
创建了一个 Runnable
对象,并调用了其 run
方法。
public static void main(String[] argv) {
...
if (startSystemServer) {
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
if (r != null) {
r.run();
return;
}
}
...
caller = zygoteServer.runSelectLoop(abiList);
...
}
forkSystemServer()
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
...
String args[] = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,"
+ "1024,1032,1065,3001,3002,3003,3006,3007,3009,3010",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server",
"--runtime-args",
"--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
"com.android.server.SystemServer",
};
ZygoteArguments parsedArgs = null;
int pid;
try {
parsedArgs = new ZygoteArguments(args);
Zygote.applyDebuggerSystemProperty(parsedArgs);
Zygote.applyInvokeWithSystemProperty(parsedArgs);
boolean profileSystemServer = SystemProperties.getBoolean(
"dalvik.vm.profilesystemserver", false);
if (profileSystemServer) {
parsedArgs.mRuntimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;
}
/* Request to fork the system server process */
pid = Zygote.forkSystemServer( // 1
parsedArgs.mUid, parsedArgs.mGid,
parsedArgs.mGids,
parsedArgs.mRuntimeFlags,
null,
parsedArgs.mPermittedCapabilities,
parsedArgs.mEffectiveCapabilities);
}
/* For child process */
if (pid == 0) {
if (hasSecondZygote(abiList)) { // 2
waitForSecondaryZygote(socketName);
}
zygoteServer.closeServerSocket(); // 3
return handleSystemServerProcess(parsedArgs); // 4
}
return null;
}
forkSystemServer()
方法主要执行了以下几个任务:
- 准备
system server
启动的参数,注释1之前的代码。 - 调用
Zygote
forkSystemServer()
出system server
进程,注释1处。 - 如果系统初始化了
SecondZygote
,则通过SecondZygote
建立连接,注释2处。 - 关闭从
zygote
进程复制的socket
,因为system server
通过binder
与其它进程通信(zygote
进程除外),注释3处。 - 最后调用
handleSystemServerProcess()
处理system server
进程初始化工作。
handleSystemServerProcess()
private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {
...
final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
if (systemServerClasspath != null) {
if (performSystemServerDexOpt(systemServerClasspath)) {
sCachedSystemServerClassLoader = null;
}
}
...
if (parsedArgs.mInvokeWith != null) {
...
WrapperInit.execApplication(parsedArgs.mInvokeWith,
parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion,
VMRuntime.getCurrentInstructionSet(), null, args);
} else {
...
return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mRemainingArgs, cl);
}
}
handleSystemServerProcess()
方法中首先会对 SystemServerClass
做dex
优化,然后根据 parsedArgs.mInvokeWith
是否为空走不同的分支,跟踪代码可知 parsedArgs.mInvokeWith == null
,即最后执行到了 ZygoteInit.zygoteInit()
。
ZygoteInit.zygoteInit()
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {
RuntimeInit.commonInit();
ZygoteInit.nativeZygoteInit();
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
zygoteInit()
方法调用了 RuntimeInit.commonInit()
和 ZygoteInit.nativeZygoteInit()
执行一些进程启动相关初始化工作,其中在 ZygoteInit.nativeZygoteInit()
调用 com_android_internal_os_RuntimeInit_nativeZygoteInit native
函数,启动了一个 binder
线程池,供system server
进程和其他进程通信使用。最后调用 RuntimeInit.applicationInit()
执行进程启动自身初始化工作。
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {
...
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
Class<?> cl;
try {
cl = Class.forName(className, true, classLoader);
}
Method m;
try {
m = cl.getMethod("main", new Class[] { String[].class });
}
return new MethodAndArgsCaller(m, argv);
}
applicationInit()
最后是通过反射调用了 SyetemServer.java
中的 main()
方法。
SyetemServer.java 解析
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
try {
...
Looper.prepareMainLooper(); // 1
System.loadLibrary("android_servers"); // 2
...
createSystemContext(); // 3
mSystemServiceManager = new SystemServiceManager(mSystemContext); // 4
mSystemServiceManager.setStartInfo(mRuntimeRestart,
mRuntimeStartElapsedTime, mRuntimeStartUptime);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
...
SystemServerInitThreadPool.get(); // 5
}
try {
startBootstrapServices(); //6
startCoreServices();
startOtherServices();
SystemServerInitThreadPool.shutdown(); // 7
}
...
Looper.loop() // 8
}
SystemServer.main()
方法中创建了 SystemServer
实例,并调用了其 run()
方法。SystemServer
进程相关的初始化任务都是在 run()
方法中完成的,其主要执行了以下任务。
- 创建当前线程
Looper
对象。 - 通过
System.loadLibrary()
加载静态库。 - 创建系统上下文对象。
- 创建
SystemServiceManager
对象,用于管理系统的各种服务。 - 创建服务初始化线程池,使得系统服务的初始化过程可并行。
- 通过
SystemServiceManager
启动各种系统服务,包括启动必需的服务、核心服务和其他服务三类(AMS
、PMS
就是在这里启动的)。 - 回收并关闭服务初始化线程池。
- 通过
Looper.loop()
进入阻塞式无限循环,直到有新的任务执行。
至此,system server
进程的启动流程就结束了。
系统服务分类
在 system server
启动过程中,系统服务被分为三类、引导服务、核心服务、其他服务。
引导服务:
-
Installer
:安装 apk 的服务 -
ActivityManagerService
:负责四大组件的启动、切换、调度。 -
PackageManagerService
:安装、卸载、解析、管理系统中的apk
。 -
PowerManagerService
:系统中power
相关的管理。 -
DisplayManagerService
:显示设备的管理。 -
SensorService
:为系统提供各种传感器的服务。
核心服务:
-
BatteryService
:电池相关的管理。 -
UsageStatsService
:用户行为和日志收集。 -
WebViewUpdateService
:webview
更新服务。
其他服务:
-
CameraService
:摄像头的管理并向系统提供相机能力。 -
AlarmManagerService
:全局定时器服务。 -
WindowManagerService
:窗口管理服务。 -
LocationManagerService
:定位服务。 -
AudioService
:音频相关管理服务。
单个服务启动流程
单个的服务通过 SystemServiceManager.startService()
接口启动,流程包括3步。
- 通过
serviceClass
对象获取其构造方法,调用构造方法创建service
实例。 - 将新建的
service
添加到服务列表mServices
中。 - 调用
service.onStart()
方法启动服务。
public <T extends SystemService> T startService(Class<T> serviceClass) {
try {
final T service;
try {
Constructor<T> constructor = serviceClass.getConstructor(Context.class);
service = constructor.newInstance(mContext);
}
startService(service);
return service;
}
}
public void startService(@NonNull final SystemService service) {
mServices.add(service);
long time = SystemClock.elapsedRealtime();
try {
service.onStart();
}
}
总结
system server
启动流程主要包括以下流程:
- 在
zygote
进程启动过程中,调用forkSystemServer()
进入system server
的创建流程 - 通过
Zygote.forkSystemServer()
复制zygote
进程,创建system server
进程。 - 调用
handleSystemServerProcess()
进入到system server
进程的初始化流程。 - 通过
ZygoteInit.zygoteInit()
调用到RuntimeInit.applicationInit()
, 然后在findStaticMain()
方法中创建了包含SystemServer.java main
方法的MethodAndArgsCaller
实例,最后返回到forkSystemServer()
调用处,调用MethodAndArgsCaller
实例的run()
方法执行到SystemServer.main()
方法中。 - 在
SystemServer.main()
方法执行到了SystemServer.run()
方法。在run()
方法中,创建了SystemServiceManager
实例,并通过SystemServiceManager
启动了各种系统服务。 - 最后
system server
进程通过Looper.loop()
进入无限循环,等待其他进程通过binder
发送新的任务。