前语
前面该系列文章咱们剖析了用户态第一个进程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记录贴