SystemServer进程的启动流程
这道题想考察什么?
这道题想考察同学对SystemServer进程的了解。
考生应该如何回答
SystemServer进程是由zygote进程启动的,它作为zygote进程的大儿子,它被赋予了重要的职责,启动并管理app运行所需要的绝大多数服务,其中包含:AMS ,ATMS,WMS,PKMS,PMS等等大概有90多个服务,这些服务的启动和管理流程的细节请看后面的分析。
1.SystemServer是做什么的
SystemServer进程主要是用于创建和管理系统服务的,例如AMS、WMS、PMS。由于SystemServer进程和应用进程由Zygote进程启动,所以接下来分析Zygote如何处理的SystemServer进程。
2.Zygote处理SystemServer进程
继上一题《Zygote进程的启动流程》的代码,在zygote#main() 函数中通过调用forkSystemServer()函数 fork SystemServer 进程,那么我们看一下下面的代码:
// frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
try {
// 1.创建SystemServer进程,并返回当前进程的pid
pid = Zygote.forkSystemServer(
parsedArgs.mUid, parsedArgs.mGid,
parsedArgs.mGids,
parsedArgs.mRuntimeFlags,
null,
parsedArgs.mPermittedCapabilities,
parsedArgs.mEffectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
// 2.如果pid==0则说明Zygote进程创建SystemServer进程成功,当前运行在SystemServer进程中
if (pid == 0) {
// 3.由于SystemServer进程fork了Zygote进程的地址空间,所以会得到Zygote进程创建的Socket,
// 而这个Socket对于SystemServer进程是无用的,因此,在此处关闭了该Socket。
zygoteServer.closeServerSocket();
// 4.启动SystemServer进程
return handleSystemServerProcess(parsedArgs);
}
}
上面的代码执行过程会涉及到进程的fork,在代码1 处,Zygote.forkSystemServer()执行的过程中会创建一个进程,这个进程就是systemServer进程。那么fork完成后,此处的代码会返回两次,因为fork 会返回两次,一次返回是执行fork新创建的代码,另外一次是zygote自己的代码。第一次返回值如果是0 ,说明当前运行的是新的创建的进程的代码也就是systemServer进程的代码,第二次返回的值是一个大于0的值,说明当前运行的代码是zygote进程的代码。因此就有了后面的if判断也就是代码2处,如果 pid 等于0 ,说明当前进程是运行在systemServer进程中。systemServer进程是不需要zygoteServer的,于是就有了 closeServerSocket代码的存在。然后,再执行handleSystemServerProcess,运行systemServer进程。
private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {
if (parsedArgs.mInvokeWith != null) {
...
} else {
ClassLoader cl = null;
if (systemServerClasspath != null) {
// 1.使用了systemServerClassPath和targetSdkVersion创建了一个PathClassLoader
cl = createPathClassLoader(systemServerClasspath, parsedArgs.mTargetSdkVersion);
}
// 2.调用 ZygoteInit.zygoteInit 方法
return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mDisabledCompatChanges,
parsedArgs.mRemainingArgs, cl);
}
}
以上代码做了两件事:1)基于sdk版本创建了一个ClassLoader;2)执行zygoteInit方法。
public static final Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,
String[] argv, ClassLoader classLoader) {
// 1.进入native方法
ZygoteInit.nativeZygoteInit();
// 2.获取封装了SystemServer的main函数的runnable
return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,
classLoader);
}
在zygoteInit函数中,首先是调用nativeZygoteinit函数来初始化进程环境,然后再执行applicationInit函数获取封装了SystemServer的main函数的Runnable。
2-1.ZygoteInit.nativeZygoteInit
在上一题《zygote进程的启动流程》中我们知道有一个流程,那就是在zygote初始化的时候会注册JNI,其中就有将nativeZygoteInit()方法和native函数com_android_internal_os_ZygoteInit_nativeZygoteInit()建立了映射关系。所以此时调用nativeZygoteInit()会调用到AndroidRuntime的下面的代码。
static AndroidRuntime* gCurRuntime = NULL;
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
gCurRuntime->onZygoteInit();
}
gCurRuntime是AndroidRuntime的指针,具体指向的是其子类AppRuntime,它在app_main.cpp中定义。代码如下:
// frameworks/base/cmds/app_process/app_main.cpp
virtual void onZygoteInit()
{
// 1.创建了一个ProcessState实例
sp<ProcessState> proc = ProcessState::self();
// 2.启动了一个Binder线程池
proc->startThreadPool();
}
在这个代码中执行的是进程的初始化,首先在代码1处,创建了一个进程ProcessState,其中就会创建一个binder;然后在代码2处启动了Binder线程池,为Binder线程的运行提供了动力。
到目前为止SystemServer进程已经创建完成,那么接下来就需要运行systemServer进程了,所以我们回到RuntimeInit.applicationInit函数中进行分析。
2-2.RuntimeInit.applicationInit
// frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,
String[] argv, ClassLoader classLoader) {
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
Class<?> cl;
try {
// 1.通过反射得到了SystemServer类
cl = Class.forName(className, true, classLoader);
}
Method m;
try {
// 2.找到了 SystemServer中的main方法
m = cl.getMethod("main", new Class[] { String[].class });
}
// 3.将main()方法传入MethodAndArgsCaller()方法中
return new MethodAndArgsCaller(m, argv);
}
以上代码就是运用反射,拿到systemServer的main 函数,并且调用MethodAndArgsCaller,将main函数的调用封装到一个Runnable中,方便后期的执行。
static class MethodAndArgsCaller implements Runnable {
private final Method mMethod;
public MethodAndArgsCaller(Method method, String[] args) {
mMethod = method;
mArgs = args;
}
public void run() {
try {
// 执行SystemServer的main()方法
mMethod.invoke(null, new Object[] { mArgs });
}
}
}
这个Runnable的run方法是在ZygoteInit的main()方法中被执行。代码如下:
// frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) {
try {
if (startSystemServer) {
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
if (r != null) {
r.run(); //1 执行run
return;
}
}
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
throw ex;
} finally {
if (zygoteServer != null) {
zygoteServer.closeServerSocket();
}
}
如上面代码1处,执行run方法,这个时候就是执行方法main(),所以,接下来我们看systemServer main函数的执行。
3. SystemServer进程执行
// frameworks/base/services/java/com/android/server/SystemServer.java
public static void main(String[] args) {
new SystemServer().run();
}
main函数就一行代码执行SystemServer进程的润函数:
private void run() {
try {
Looper.prepareMainLooper();
// 1.加载动态库libandroid_servers.so
System.loadLibrary("android_servers");
// 2.创建SystemServerManager
mSystemServiceManager = new SystemServiceManager(mSystemContext);
// 3.初始化系统上下文
createSystemContext();
}
try {
// 3.使用SystemServiceManager启动引导服务
startBootstrapServices(t);
// 4.启动核心服务
startCoreServices(t);
// 5.启动其他服务
startOtherServices(t);
}
// Loop forever.
Looper.loop();
}
通过上面的代码不难发现,启动过程中,在大流程上systemServer和app进程的启动很像,初始化了很多资源,也加载了很多资源,还创建了上下文,同时构建了进程的Looper 死循环确保进程不会退出。当然,在SystemServer中最重要的内容还是通过代码3,4,5启动了非常多的服务,大概有90多个服务,这些服务包括AMS,ATMS,WMS,PKMS,BMS等等一系列的服务。另外,在代码2处创建了一个systemServiceManager对象,这个对象是用于在SystemServer进程中管理90多个服务的启动的。
4.总结
SystemService进程被创建后,主要的处理如下:
- 启动Binder线程池,这样就可以与其他进程进行Binder跨进程通信。
- SystemServer在启动过程中,先初始化一些系统变量,加载类库,创建Context对象。
- 创建SystemServiceManager,它用来对系统服务进行创建、启动和生命周期管理。
- 启动各种系统服务:引导服务、核心服务、其他服务,共90多种。应用开发主要关注引导服务ActivityManagerService、PackageManagerService和其他服务WindowManagerService、InputManagerService即可。
- SystemServer在启动服务前,会尝试与Zygote建立Socket通信,通信成功后才去启动服务。
- 启动的服务都单独运行在SystemServer的各自线程中,同属于SystemServer进程
最后
我整理了一套Android面试题合集,除了以上面试题,还包含【Java 基础、集合、多线程、虚拟机、反射、泛型、并发编程、Android四大组件、异步任务和消息机制、UI绘制、性能调优、SDN、第三方框架、设计模式、Kotlin、计算机网络、系统启动流程、Dart、Flutter、算法和数据结构、NDK、H.264、H.265.音频编解码、FFmpeg、OpenMax、OpenCV、OpenGL ES】