Android启动过程简析(三)之 SystemServer 进程

前言

Android启动过程简析(二)中已经大致分析了 zygote 进程的启动过程当中所做的主要工作,本篇将继续对 SystemServer 的启动过程进行分析。

SystemServer 启动过程

上文说到 SystemServer 进程在 ZygoteInit.java 中被创建,然后便会在 SystemServer 进程调用 handleSystemServerProcess 方法处理 SystemServer 进程的剩余工作

frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
private static void handleSystemServerProcess(
ZygoteConnection.Arguments parsedArgs)
throws ZygoteInit.MethodAndArgsCaller {

//SystemServer 进程不需要进行Socket通信,所以关闭
closeServerSocket();
...

//设置进程名为system_server
if (parsedArgs.niceName != null) {
Process.setArgV0(parsedArgs.niceName);
}

final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
...

//这里 parsedArgs.invokeWith 为 null
if (parsedArgs.invokeWith != null) {
....
} else {
ClassLoader cl = null;
if (systemServerClasspath != null) {
//创建 SystemServer 的类加载器对象
cl = createSystemServerClassLoader(systemServerClasspath,
parsedArgs.targetSdkVersion);

Thread.currentThread().setContextClassLoader(cl);
}

//将剩余参数传递给 SystemServer
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}

/* should never reach here */
}

在 handleSystemServerProcess 方法中首先会关闭掉 Socket 连接,然后会根据传递过来的参数设置进程名称,在设置完进程名称之后,由于 parseArgs 的成员 invokeWith 为 null,所以会利用 systemServerClasspath 创建对应的类加载器对象,最后会通过 RuntimeInit 的 zygoteInit 方法将剩余参数传递给 SystemServer。

RuntimeInit 分析

frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

1
2
3
4
5
6
7
8
9
10
11
public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");

Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "RuntimeInit");
redirectLogStreams();

commonInit();
nativeZygoteInit();
applicationInit(targetSdkVersion, argv, classLoader);
}

zygoteInit 中依次调用了 nativeZygoteInit 和 applicationInit,其中前者启动了一个线程池,而后者则会调用了 SystemServer 类的 main 方法。

启动线程池

nativeZygoteInit 实际上对应着 com_android_internal_os_RuntimeInit_nativeZygoteInit

frameworks/base/core/jni/AndroidRuntime.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
static const JNINativeMethod gMethods[] = {
{ "nativeFinishInit", "()V",
(void*) com_android_internal_os_RuntimeInit_nativeFinishInit },
{ "nativeZygoteInit", "()V",
(void*) com_android_internal_os_RuntimeInit_nativeZygoteInit },
{ "nativeSetExitWithoutCleanup", "(Z)V",
(void*) com_android_internal_os_RuntimeInit_nativeSetExitWithoutCleanup },
};

int register_com_android_internal_os_RuntimeInit(JNIEnv* env)
{
return jniRegisterNativeMethods(env, "com/android/internal/os/RuntimeInit",
gMethods, NELEM(gMethods));
}

继续查看 com_android_internal_os_RuntimeInit_nativeZygoteInit 可以知道最终调用了 gCurRuntime 的 onZygoteInit 方法,而 gCurRuntime 实际上是一个 AndroidRuntime 的指针

1
2
3
4
static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
gCurRuntime->onZygoteInit();
}

onZygoteInit 的具体实现在 AndroidRuntime 的子类 AppRuntime 中,可以看到最终通过 startThreadPool 启动了线程池

frameworks/base/cmds/app_process/app_main.cpp

1
2
3
4
5
6
virtual void onZygoteInit()
{
sp<ProcessState> proc = ProcessState::self();
ALOGV("App process: starting thread pool.\n");
proc->startThreadPool();
}

调用 SystemServer 的 main 方法

frameworks/base/core/java/com/android/internal/os/RuntimeInit.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
...

//根据 argv 构建 RuntimeInit.Arguments,这里的 argv[] 实际上是 “com.android.server.SystemServer”
final Arguments args;
try {
args = new Arguments(argv);
} catch (IllegalArgumentException ex) {
Slog.e(TAG, ex.getMessage());
// let the process exit
return;
}

// The end of of the RuntimeInit event (see #zygoteInit).
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

// Remaining arguments are passed to the start class's static main
invokeStaticMain(args.startClass, args.startArgs, classLoader);
}

在 applicationInit 方法中会对 argv 进行解析创建 RuntimeInit.Arguments 参数,然后会调用 invokeStaticMain

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
Class<?> cl;

try {
//获取SystemServer的Class对象
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {
throw new RuntimeException(
"Missing class when invoking static main " + className,
ex);
}

Method m;
try {
//获取 main 方法
m = cl.getMethod("main", new Class[] { String[].class });
} catch (NoSuchMethodException ex) {
throw new RuntimeException(
"Missing static main on " + className, ex);
} catch (SecurityException ex) {
throw new RuntimeException(
"Problem getting static main on " + className, ex);
}

//获取方法修饰符,判断是否是入口 main 方法
int modifiers = m.getModifiers();
if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
throw new RuntimeException(
"Main method is not public and static on " + className);
}

/*
* This throw gets caught in ZygoteInit.main(), which responds
* by invoking the exception's run() method. This arrangement
* clears up all the stack frames that were required in setting
* up the process.
*/
throw new ZygoteInit.MethodAndArgsCaller(m, argv);
}

在 invokeStaticMain 方法中会通过方法签名获取到 SystemServer 的 main 方法,之后会抛出 MethodAndArgsCaller 异常,然后在 ZygoteInit 的 main 方法中进行捕获,捕获之后会执行 MethodAndArgsCaller 的 run 方法,而在 run 方法中会完成对 SystemServer 的 main 方法的调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//MethodAndArgsCaller 的 run 方法
public void run() {
try {
mMethod.invoke(null, new Object[] { mArgs });
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (InvocationTargetException ex) {
Throwable cause = ex.getCause();
if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
} else if (cause instanceof Error) {
throw (Error) cause;
}
throw new RuntimeException(ex);
}
}

//ZygoteInit 捕获异常
//frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) {
...
} catch (MethodAndArgsCaller caller) {
caller.run();
}
....
}

SystemServer 分析

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

SystemServer 的 main 方法中创建了一个 SystemServer 对象,并调用了其 run 方法,所以继续看 run 方法部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
private void run() {
try {
...
//创建 SystemServer 主线程的 Looper
Looper.prepareMainLooper();

// 初始化 mSystemContext
createSystemContext();

// 创建 SystemServiceManager 对象
mSystemServiceManager = new SystemServiceManager(mSystemContext);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}

// 启动服务
try {
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices");
startBootstrapServices();
startCoreServices();
startOtherServices();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}

// For debug builds, log event loop stalls to dropbox for analysis.
if (StrictMode.conditionallyEnableDebugLogging()) {
Slog.i(TAG, "Enabled StrictMode for system server main thread.");
}

// Loop forever.
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}

在 run 方法中,首先调用 Looper.prepareMainLooper() 创建了当前主线程的 Looper,之后会调用 createSystemContext 初始化 mSystemContext 实例,这里的 mSystemContext 是一个 ContextImpl 实例,主要用于初始化一些 Service,最后则是启动系统各项服务。

启动系统服务

从启动服务的过程中看,系统将服务分为三类:

  1. 引导服务----------startBootstrapServices()

    Installer、ActivityManagerService、PackageManagerService 等

  2. 核心服务----------startCoreServices()

    BatteryService、UsageStatsService、WebViewUpdateService

  3. 其它服务----------startOtherServices()

    AlarmManagerService、VibratorService 等

而对于服务的启动方式而言也分为三种(启动方式与服务类别并不对应):

  1. mSystemServiceManager.startService()

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    public <T extends SystemService> T startService(Class<T> serviceClass) {
    try {
    final String name = serviceClass.getName();
    ...
    //创建Service实例
    final T service;
    try {
    Constructor<T> constructor = serviceClass.getConstructor(Context.class);
    service = constructor.newInstance(mContext);
    } catch (InstantiationException ex) {
    ....
    }

    // 加入 List<SystemService> 当中
    mServices.add(service);

    //回调 Service 的 onStart 方法
    try {
    service.onStart();
    } catch (RuntimeException ex) {
    throw new RuntimeException("Failed to start service " + name
    + ": onStart threw an exception", ex);
    }
    return service;
    } finally {
    Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
    }
    }

    从这里可以看出 startService 启动的服务都是 SystemService 的子类,启动的过程是先对服务类进行加载,加载之后进行实例化,实例化之后则会调用实例的 onStart 方法。

  2. xxxService.main()

    这种方式主要在启动以下三个服务中用到

    • PackageManagerService

    • OtaDexoptService
    • WindowManagerService

    这里以 PackageManagerService 为例进行分析

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public static PackageManagerService main(Context context, Installer installer,
    boolean factoryTest, boolean onlyCore) {
    // Self-check for initial settings.
    PackageManagerServiceCompilerMapping.checkProperties();

    PackageManagerService m = new PackageManagerService(context, installer,
    factoryTest, onlyCore);
    m.enableSystemUserPackages();

    //注册启动服务
    ServiceManager.addService("package", m);
    return m;
    }

    可以看到在 main 方法中直接创建了 PackageManagerService 的实例,然后通过 ServiceManager 进行注册启动。

  3. ServiceManager.addService()

    1
    ServiceManager.addService("scheduling_policy", new SchedulingPolicyService());

    ServiceManager 涉及到 Binder 暂不做分析

上文中提到了服务的注册,对于服务的注册而言实际上分为两种:一是 ServiceManager.addService,二是 LocalServices.addService

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**
* This class is used in a similar way as ServiceManager, except the services registered here
* are not Binder objects and are only available in the same process.
*
* Once all services are converted to the SystemService interface, this class can be absorbed
* into SystemServiceManager.
*
* {@hide}
*/
public final class LocalServices {
private LocalServices() {}

private static final ArrayMap<Class<?>, Object> sLocalServiceObjects =
new ArrayMap<Class<?>, Object>();

...

/**
* Adds a service instance of the specified interface to the global registry of local services.
*/
public static <T> void addService(Class<T> type, T service) {
synchronized (sLocalServiceObjects) {
if (sLocalServiceObjects.containsKey(type)) {
throw new IllegalStateException("Overriding service registration");
}
sLocalServiceObjects.put(type, service);
}
}

...
}

查看 LocalServices 的类描述可以知道 LocalServices 与 ServiceManager 用处类似,不同点在于ServiceManager 用于不同进程间获取 Service,而 LocalServices 只能够用于同一进程中获取 Service。

总结

至此大概就能知道在 SystemServer 启动过程中主要做了三件事

  1. 开启线程池
  2. 创建 SystemServerManager 对象负责继承自 SystemService 的服务的创建、启动以及生命周期的管理
  3. 启动系统的服务

Thanks

  1. Android系统启动-SystemServer上篇
  2. Android系统启动-SystemServer下篇
  3. Android系统服务的注册方式
  4. Android系统启动流程(三)解析SyetemServer进程启动过程