前言
前面该系列文章我们分析了用户态第一个进程init进程,和开启Java世界的Zygote进程的流程分析,本篇文章我们来分析一下SystemServer进程,即系统服务进程。
系统服务进程由Zygote进程创建而来,它的作用是用于创建和管理系统服务,比如我们熟知的AMS、WMS和PMS等都是由它来创建的,所以它可以看成是Java Framework的管理者。
正文
话不多说,我们就来看看该进程的启动流程。
Zygote启动SystemServer进程
该部分内容在上一篇Zygote进程分析中有所涉及,主要就是ZygoteInit中的forkSystemServer方法,在该方法中底层通过fork系统调用先创建进程,然后调用handleSystemServerProcess方法来处理系统服务进程。大致代码如下:
/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
private static Runnable forkSystemServer(String abiList, String socketName,
621 ZygoteServer zygoteServer) {
622 ...
//各种参数
641 String args[] = {
642 "--setuid=1000",
643 "--setgid=1000",
644 "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1032,3001,3002,3003,3006,3007,3009,3010",
645 "--capabilities=" + capabilities + "," + capabilities,
646 "--nice-name=system_server",
647 "--runtime-args",
//最后调用的Java类
648 "com.android.server.SystemServer",
649 };
650 ZygoteConnection.Arguments parsedArgs = null;
651
652 int pid;
653
654 try {
655 parsedArgs = new ZygoteConnection.Arguments(args);
656 ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
657 ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
658
//通过fork创建了新进程,即系统服务进程
660 pid = Zygote.forkSystemServer(
661 parsedArgs.uid, parsedArgs.gid,
662 parsedArgs.gids,
663 parsedArgs.debugFlags,
664 null,
665 parsedArgs.permittedCapabilities,
666 parsedArgs.effectiveCapabilities);
667 } catch (IllegalArgumentException ex) {
668 throw new RuntimeException(ex);
669 }
670
671 //系统服务进程运行分支
672 if (pid == 0) {
673 if (hasSecondZygote(abiList)) {
674 waitForSecondaryZygote(socketName);
675 }
676 //系统服务进程不需要监听socket,所以关闭
677 zygoteServer.closeServerSocket();
//处理系统服务进程
678 return handleSystemServerProcess(parsedArgs);
679 }
680
681 return null;
682 }
所以这里主要逻辑就来到了handleSystemServerProcess方法,由该方法开启系统服务进程的业务流程。
SystemServer业务流程分析
我们来看看主要逻辑的方法:
/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
453 ...
500 } else {
501 ClassLoader cl = null;
502 if (systemServerClasspath != null) {
//创建PathClassLoader
503 cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
504
505 Thread.currentThread().setContextClassLoader(cl);
506 }
//初始化
511 return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
512 }
513
514 /* should never reach here */
515 }
这里首先是创建PathClassLoader,关于类加载,我们后面文章细说,然后调用了ZygoteInit的zygoteInit函数:
/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
852 if (RuntimeInit.DEBUG) {
853 Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
854 }
855
856 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
857 RuntimeInit.redirectLogStreams();
858
859 RuntimeInit.commonInit();
//这里启动了Binder线程池
860 ZygoteInit.nativeZygoteInit();
//初始化业务
861 return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
862 }
这个方法中先启动了Binder线程池,然后开始进行系统服务进程的各种服务启动、管理工作。
这里有个很关键的点,就是启动Binder线程池,关于Binder通信我们最熟悉的就是AIDL,而AIDL或者Binder的工作原理中服务端需要有一个线程池来处理客户端的请求,这里给出一张AIDL工作原理图:
从上图我们可以发现Binder通信是基于C/S架构的,服务端处理数据会放入线程池中处理,所以每个需要使用Binder通信的进程都必须要创建Binder线程池。
这也从另一个方面验证了一点,即上面启动进程的zygoteInit函数,都会创建一个用于Binder通信的线程池,而上一篇文章所说的Zygote进程却没有这个,所以和Zygote进程通信方式还是Socket,从SystemServer开始,系统服务进程和其他进程比如APP进程,就是使用Binder了。
启动Binder线程池
关于Binder的设计非常复杂,涉及知识点特别多,后续我们仔细说,这里先看看如何启动Binder线程池。
nativeZygoteInit方法是一个native方法,因此我们需要找到它的JNI文件,找到对应的C++文件。由Java文件定义的native方法,找到JNI方法是有技巧的,比如这里的方法和类名分别是com.android.internal.os.ZygoteInit和nativeZygoteInit,所以它对应的JNI函数名就是把Java中的.换成_,即com_android_internal_os_ZygoteInit_nativeZygoteInit方法,该方法定义:
/frameworks/base/core/jni/AndroidRuntime.cpp
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
223 {
224 gCurRuntime->onZygoteInit();
225 }
这里关于JNI类型的细节我们不做讨论,我们可以成功找到该上面本地方法对应的C++代码,当然这种按名字的找法不一定对,因为Java中定义一个Native方法和其C/c++实现方法是通过JNI注册来做的一一对应关系,注册如下:
/frameworks/base/core/jni/AndroidRuntime.cpp
int register_com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env)
250 {
251 const JNINativeMethod methods[] = {
252 { "nativeZygoteInit", "()V",
253 (void*) com_android_internal_os_ZygoteInit_nativeZygoteInit },
254 };
255 return jniRegisterNativeMethods(env, "com/android/internal/os/ZygoteInit",
256 methods, NELEM(methods));
257 }
关于jni注册的原理我们后面JNI文章再说。
这里我们就只需要知道,在上面Java文件中定义的Native方法对应着com_android_internal_os_ZygoteInit_nativeZygoteInit即可。
在该方法中,gCurRuntime就是AppRuntime(AndroidRuntime子类)的对象,这里是其成员方法:
/frameworks/base/cmds/app_process/app_main.cpp
virtual void onZygoteInit()
92 {
93 sp<ProcessState> proc = ProcessState::self();
94 ALOGV("App process: starting thread pool.\n");
95 proc->startThreadPool();
96 }
这里又调用了ProcessState的startThreadPool方法,这个ProcessState是Binder相关的类,这里方法就是创建线程池,我们不继续向下分析了。
分析这里主要就是给大家说一下如何找到JNI方法对应的C/C++方法,关于JNI原理后面文章细说。
SystemServer业务流程
在上面创建完Binder线程池后,会调用RuntimeInit中的applicationInit静态方法:
/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
291 ClassLoader classLoader) {
292 ...
310 return findStaticMain(args.startClass, args.startArgs, classLoader);
311 }
然后调用findStaticMain方法:
/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
private static Runnable findStaticMain(String className, String[] argv,
233 ClassLoader classLoader) {
234 Class<?> cl;
//这里的className为com.android.server.SystemServer
//通过反射找到SystemServer的Java类
236 try {
237 cl = Class.forName(className, true, classLoader);
238 } catch (ClassNotFoundException ex) {
239 throw new RuntimeException(
240 "Missing class when invoking static main " + className,
241 ex);
242 }
243
244 Method m;
//找到SystemServer的main方法
245 try {
246 m = cl.getMethod("main", new Class[] { String[].class });
247 } catch (NoSuchMethodException ex) {
248 throw new RuntimeException(
249 "Missing static main on " + className, ex);
250 } catch (SecurityException ex) {
251 throw new RuntimeException(
252 "Problem getting static main on " + className, ex);
253 }
254
255 int modifiers = m.getModifiers();
256 if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
257 throw new RuntimeException(
258 "Main method is not public and static on " + className);
259 }
260
261 //调用main方法
267 return new MethodAndArgsCaller(m, argv);
268 }
这里我们的调用流程就转移到了SystemServer.java的main方法:
/frameworks/base/services/java/com/android/server/SystemServer.java
public static void main(String[] args) {
267 new SystemServer().run();
268 }
/frameworks/base/services/java/com/android/server/SystemServer.java
private void run() {
278 try {
279 ...
//创建消息Looper,用于线程间通信
364 Looper.prepareMainLooper();
365
366 //加载native库
367 System.loadLibrary("android_servers");
368
371 performPendingShutdown();
372
373 //创建系统的Context
374 createSystemContext();
375
376 //创建系统服务管理类
377 mSystemServiceManager = new SystemServiceManager(mSystemContext);
378 mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
379 LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
380 // Prepare the thread pool for init tasks that can be parallelized
381 SystemServerInitThreadPool.get();
382 } finally {
383 traceEnd(); // InitBeforeStartServices
384 }
385
386 //开始开启各种服务
387 try {
388 traceBeginAndSlog("StartServices");
//开始引导服务
389 startBootstrapServices();
//开始核心服务
390 startCoreServices();
//开始其他服务
391 startOtherServices();
392 SystemServerInitThreadPool.shutdown();
393 } catch (Throwable ex) {
394 Slog.e("System", "******************************************");
395 Slog.e("System", "************ Failure starting system services", ex);
396 throw ex;
397 } finally {
398 traceEnd();
399 }
...
401 //开始loop
416 Looper.loop();
417 throw new RuntimeException("Main thread loop unexpectedly exited");
418 }
这里就是SystemServer进程所做的事情,主要包括:
- 创建和循环Looper,这个用于线程间通信,关于Handler知识,后面将会从应用层到底层仔细分析;
- 加载了动态库libandroid_servers.so,这里是为了找到Native层的C/C++代码;
- 创建系统Context,关于Context我们后面文章单独分析。
- 创建了系统服务管理类实例mSystemServiceManager,它的类型是SystemServiceManager,用来创建、启动以及管理系统服务的一些生命周期事件。
然后主要工作就是开启各种服务,这里的服务主要分为3类,一共加起来有好几十个,下面列举一些主要的服务:
引导服务 | 作用 |
---|---|
Installer | 系统安装APK时的一个服务类,启动完成Installer服务之后才能其他其他的系统服务 |
ActivityManagerService | 负责四大组件的启动、切换和调度 |
PowerManagerService | 计算系统中和Power相关的计算,然后决策系统应该如何反应 |
LightsService | 管理和显示背光LED |
DisplayManagerService | 用来管理所有显示设备 |
UserManagerService | 多用户模式管理 |
SensorService | 为消停提供各种感应服务 |
PackageManagerService | 用来对APK进行安装、解析、删除、卸载等操作 |
核心服务 | 作用 |
---|---|
DropBoxManagerService | 用于生成和管理系统允许时的一些日志文件 |
Battery | 管理电池的服务 |
UsageStatsService | 收集用户使用每一个APP的评率、时长等 |
其他服务 | 作用 |
---|---|
CameraService | 摄像头相关服务 |
AlarmManagerService | 全局定时器管理服务 |
InputManagerService | 管理输入事件 |
WindowManagerService | 窗口管理服务 |
BluetoothService | 蓝牙管理服务 |
等等
这些系统服务承担了Android系统的各种职责,通过相互合作让我们可以使用和开发上层应用,这些服务特别多,也不用都需要掌握,一般都是了解其中重要的几个。
当然本章内容不是介绍这些服务,而是说服务启动,这里以PowerManagerService和PackageManagerService来举例。
启动服务细节
这里我们先看PowerManagerService的启动流程,首先是SystemService.java中的startBootstrapServices()函数中调用:
/frameworks/base/services/java/com/android/server/SystemServer.java
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
这里调用SystemServiceManager.java中的startService方法,该方法有好几个重载方法,先调用下面这个:
/frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
//创建和启动一个系统服务,该服务必须是SystemService的子类
public <T extends SystemService> T startService(Class<T> serviceClass) {
83 ...
//通过反射创建系统服务实例
93 final T service;
94 try {
95 Constructor<T> constructor = serviceClass.getConstructor(Context.class);
96 service = constructor.newInstance(mContext);
97 } catch (InstantiationException ex) {
98 throw new RuntimeException("Failed to create service " + name
99 + ": service could not be instantiated", ex);
100 } catch (IllegalAccessException ex) {
101 throw new RuntimeException("Failed to create service " + name
102 + ": service must have a public constructor with a Context argument", ex);
103 } catch (NoSuchMethodException ex) {
104 throw new RuntimeException("Failed to create service " + name
105 + ": service must have a public constructor with a Context argument", ex);
106 } catch (InvocationTargetException ex) {
107 throw new RuntimeException("Failed to create service " + name
108 + ": service constructor threw an exception", ex);
109 }
//启动服务
111 startService(service);
112 return service;
113 } finally {
114 Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
115 }
116 }
这里代码比较简单就是通过反射创建其实例,这里必须注意一点就是所有系统服务都必须是SystemServer.java的子类,然后这里再调用另一个重载函数startService:
/frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
public void startService(@NonNull final SystemService service) {
//注册该service
120 mServices.add(service);
122 long time = SystemClock.elapsedRealtime();
123 try {
//开启服务
124 service.onStart();
125 } catch (RuntimeException ex) {
126 throw new RuntimeException("Failed to start service " + service.getClass().getName()
127 + ": onStart threw an exception", ex);
128 }
129 warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");
130 }
这里的mServices就是一个ArrayList,保存着需要接收响应事件的系统服务,然后就是调用其onStart()方法:
/frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
@Override
686 public void onStart() {
//发布到Binder服务中
687 publishBinderService(Context.POWER_SERVICE, new BinderService());
688 publishLocalService(PowerManagerInternal.class, new LocalService());
689
690 Watchdog.getInstance().addMonitor(this);
691 Watchdog.getInstance().addThread(mHandler);
692 }
这里我们来重点看一下这个发布到Binder服务中的操作,因为这个涉及Binder通信,先看一下这个BinderService是啥:
private final class BinderService extends IPowerManager.Stub
这里的代码熟悉AIDL的应该知道,这里会定义一个IPowerManager.aidl的远程接口,用于IPC,然后这里的IPowerManager.Stub则是生成的Java类,实现了IBinder接口,是一个Binder对象,所以这里发布到Binder服务中的是一个Binder实例,接着看一下publishBinderService方法:
/frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
198 protected final void publishBinderService(String name, IBinder service) {
199 publishBinderService(name, service, false);
200 }
201
205 protected final void publishBinderService(String name, IBinder service,
206 boolean allowIsolated) {
207 ServiceManager.addService(name, service, allowIsolated);
208 }
这里最终会通过ServiceManager把刚刚那个Binder给添加进来,更多关于ServiceManager的内容,后面介绍Binder时再细说。
这里给AIDL通信简单画个时序示意图:
sequenceDiagram
SystemServer ->> PowerManagerService:创建、启动服务
PowerManagerService ->> PowerManagerService:new BinderService() 获取Binder对象
PowerManagerService ->> SystemServiceManager:publishBinderService() 传递Binder对象
SystemServiceManager ->> ServiceManager:addService 注册Binder
应用进程X ->> SystemServiceManager:想和PowerManagerService通信
SystemServiceManager ->> 应用进程X:返回Binder引用
Note over 应用进程X,PowerManagerService:应用进程X和PowerManagerService通过Binder进行通信
由上面图我们可知能进行Binder跨进程通信的前提还得需要注册和"中间人"角色。
除了通过用mSystemServiceManager的startService启动系统服务外,还可以通过下面方式启动,我们以PMS为例:
/frameworks/base/services/java/com/android/server/SystemServer.java
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
586 mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
public static PackageManagerService main(Context context, Installer installer,
2347 boolean factoryTest, boolean onlyCore) {
2348
2349 PackageManagerServiceCompilerMapping.checkProperties();
2350
//通过new创建对象
2351 PackageManagerService m = new PackageManagerService(context, installer,
2352 factoryTest, onlyCore);
2353 m.enableSystemUserPackages();
2354 ServiceManager.addService("package", m);
2355 final PackageManagerNative pmn = m.new PackageManagerNative();
2356
//注册Binder
ServiceManager.addService("package_native", pmn);
2357 return m;
2358 }
这里可以直接调用系统服务的main函数来创建和启动系统服务,同样也必不可少地需要注册Binder到ServiceManager中。
总结
系统服务进程被创建后,先创建了Context、开启Looper、加载so等常规操作,主要的工作如下:
- 启动Binder线程池,为Binder服务做基础,因为Binder通信需要线程池来处理请求。
- 创建SystemServiceManager,用于对系统服务进行创建、启动和生命周期管理。
- 启动各种服务,在各种服务中都少不了注册Binder,为了通过Binder和其他进程通信。
随着Android系统代码的梳理,一方面逐渐了理解了各种设计的巧妙和新知识,一方面也发现很多技术债,比如前面的Linux、JNI、so库等技术,还有本章涉及的Context、Looper等知识,这些知识很多之前都涉及过,但是没有个系统理解和总结,总是感觉无法完全理解,还需要不断加油突破这些难点。
笔者水平有限,文中有问题,欢迎指正。最后记录一下Flag。# 一个Android开发的学习Flag记录贴