Android启动过程简析(三)之 SystemServer 进程
前言
在Android启动过程简析(二)中已经大致分析了 zygote 进程的启动过程当中所做的主要工作,本篇将继续对 SystemServer 的启动过程进行分析。
SystemServer 启动过程
上文说到 SystemServer 进程在 ZygoteInit.java 中被创建,然后便会在 SystemServer 进程调用 handleSystemServerProcess 方法处理 SystemServer 进程的剩余工作
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
1 | private static void handleSystemServerProcess( |
在 handleSystemServerProcess 方法中首先会关闭掉 Socket 连接,然后会根据传递过来的参数设置进程名称,在设置完进程名称之后,由于 parseArgs 的成员 invokeWith 为 null,所以会利用 systemServerClasspath 创建对应的类加载器对象,最后会通过 RuntimeInit 的 zygoteInit 方法将剩余参数传递给 SystemServer。
RuntimeInit 分析
frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
1 | public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) |
zygoteInit 中依次调用了 nativeZygoteInit 和 applicationInit,其中前者启动了一个线程池,而后者则会调用了 SystemServer 类的 main 方法。
启动线程池
nativeZygoteInit 实际上对应着 com_android_internal_os_RuntimeInit_nativeZygoteInit
frameworks/base/core/jni/AndroidRuntime.cpp
1 | static const JNINativeMethod gMethods[] = { |
继续查看 com_android_internal_os_RuntimeInit_nativeZygoteInit 可以知道最终调用了 gCurRuntime 的 onZygoteInit 方法,而 gCurRuntime 实际上是一个 AndroidRuntime 的指针
1 | static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz) |
onZygoteInit 的具体实现在 AndroidRuntime 的子类 AppRuntime 中,可以看到最终通过 startThreadPool 启动了线程池
frameworks/base/cmds/app_process/app_main.cpp
1 | virtual void onZygoteInit() |
调用 SystemServer 的 main 方法
frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
1 | private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) |
在 applicationInit 方法中会对 argv 进行解析创建 RuntimeInit.Arguments 参数,然后会调用 invokeStaticMain
1 | private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader) |
在 invokeStaticMain 方法中会通过方法签名获取到 SystemServer 的 main 方法,之后会抛出 MethodAndArgsCaller 异常,然后在 ZygoteInit 的 main 方法中进行捕获,捕获之后会执行 MethodAndArgsCaller 的 run 方法,而在 run 方法中会完成对 SystemServer 的 main 方法的调用
1 | //MethodAndArgsCaller 的 run 方法 |
SystemServer 分析
1 | public static void main(String[] args) { |
SystemServer 的 main 方法中创建了一个 SystemServer 对象,并调用了其 run 方法,所以继续看 run 方法部分
1 | private void run() { |
在 run 方法中,首先调用 Looper.prepareMainLooper() 创建了当前主线程的 Looper,之后会调用 createSystemContext 初始化 mSystemContext 实例,这里的 mSystemContext 是一个 ContextImpl 实例,主要用于初始化一些 Service,最后则是启动系统各项服务。
启动系统服务
从启动服务的过程中看,系统将服务分为三类:
引导服务----------startBootstrapServices()
Installer、ActivityManagerService、PackageManagerService 等
核心服务----------startCoreServices()
BatteryService、UsageStatsService、WebViewUpdateService
其它服务----------startOtherServices()
AlarmManagerService、VibratorService 等
而对于服务的启动方式而言也分为三种(启动方式与服务类别并不对应):
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
28public <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 方法。
xxxService.main()
这种方式主要在启动以下三个服务中用到
PackageManagerService
- OtaDexoptService
WindowManagerService
这里以 PackageManagerService 为例进行分析
1
2
3
4
5
6
7
8
9
10
11
12
13public 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 进行注册启动。
ServiceManager.addService()
1
ServiceManager.addService("scheduling_policy", new SchedulingPolicyService());
ServiceManager 涉及到 Binder 暂不做分析
上文中提到了服务的注册,对于服务的注册而言实际上分为两种:一是 ServiceManager.addService,二是 LocalServices.addService
1 | /** |
查看 LocalServices 的类描述可以知道 LocalServices 与 ServiceManager 用处类似,不同点在于ServiceManager 用于不同进程间获取 Service,而 LocalServices 只能够用于同一进程中获取 Service。
总结
至此大概就能知道在 SystemServer 启动过程中主要做了三件事
- 开启线程池
- 创建 SystemServerManager 对象负责继承自 SystemService 的服务的创建、启动以及生命周期的管理
- 启动系统的服务
Thanks
- Android系统启动-SystemServer上篇
- Android系统启动-SystemServer下篇
- Android系统服务的注册方式
- Android系统启动流程(三)解析SyetemServer进程启动过程