![Android进阶解密](https://wfqqreader-1252317822.image.myqcloud.com/cover/331/31186331/b_31186331.jpg)
2.3 SystemServer处理过程
SystemServer进程主要用于创建系统服务,我们熟知的AMS、WMS和PMS都是由它来创建的,本书后面的章节会介绍AMS和WMS,因此掌握SystemServer进程是如何启动的,它在启动时做了哪些工作是十分必要的。
2.3.1 Zygote处理SystemServer进程
在2.2节中讲到了Zygote进程启动了SystemServer进程,本节来学习Zygote是如何处理SystemServer进程的,时序图如图2-2所示。
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer737.jpg?sign=1739351505-w6IjlgAKXYGcsTWM3oKufYxya0icIlpz-0-8e22a344e4330d09b17f1ae953868d5c)
图2-2 Zygote处理SystemServer进程的时序图
在ZygoteInit.java的startSystemServer方法中启动了SystemServer进程,如下所示:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer738.jpg?sign=1739351505-zRIsXVLNittGaQxQGlMd6Cz7Liy4Qcxl-0-765e34eb0524de000fcffb1c4f085132)
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer739.jpg?sign=1739351505-bYH6hgYp1hyDpS6AQbh8LlZfs9pVXoWk-0-b19020d9ff696c1b9630b59079118fbd)
SystemServer 进程复制了Zygote进程的地址空间,因此也会得到Zygote进程创建的Socket,这个Socket对于SystemServer进程没有用处,因此,需要注释1处的代码来关闭该Socket,接着在注释2处调用handleSystemServerProcess方法来启动SystemServer进程。handleSystemServerProcess方法的代码如下所示:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer740.jpg?sign=1739351505-qWWZxxxBhtnn0dTtSG0EsmQu9ydHsjqA-0-6393a3ae1dd59f6b6d3404c71c8e776d)
在注释1处创建了PathClassLoader,关于PathClassLoader将在第12章进行介绍。在注释2处调用了ZygoteInit的zygoteInit方法,代码如下所示:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer741.jpg?sign=1739351505-ovR6dZExGl0VHiZZN9bKtc7Y0Ba97Gqw-0-a42e7794a981432b1ee18b88b112cfe1)
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer742.jpg?sign=1739351505-KToJ2jaIBxdkcmsoy7XyUEnHmuTizQ06-0-0bbe57bfe8bc6de0f2ecfb8012d686db)
在注释1处调用nativeZygoteInit方法,一看方法的名称就知道调用的是Native层的代码,用来启动Binder线程池,这样SystemServer进程就可以使用Binder与其他进程进行通信了。注释2处是用于进入SystemServer的main方法,现在分别对注释1和注释2的内容进行介绍。
1.启动Binder线程池
nativeZygoteInit是一个Native方法,因此我们先要了解它对应的JNI文件,不了解JNI的可以查看第9章内容,如下所示:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer743.jpg?sign=1739351505-A5ZCAygp1wQLsozsjaNH2xvZbUZkzjL2-0-c9c3ccad2a9b41fefa43404cc827b704)
通过JNI的gMethods数组,可以看出nativeZygoteInit方法对应的是JNI文件AndroidRuntime.cpp的com_android_internal_os_ZygoteInit_nativeZygoteInit函数:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer744.jpg?sign=1739351505-MnJ0q5w9Voh62anmD9cYtieHS5Kds7qN-0-775f03aabc6a9503365b61a10aa60bdf)
这里gCurRuntime是AndroidRuntime类型的指针,具体指向的是AndroidRuntime的子类AppRuntime,它在app_main.cpp中定义,我们接着来查看AppRuntime的onZygoteInit方法,代码如下所示:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer745.jpg?sign=1739351505-e0P29SnGoFHNpI6LVfno3eNw4t30fLvq-0-b5fdceed172e18eb95cca546a97469c7)
注释1处的代码用来启动一个Binder线程池,这样SystemServer进程就可以使用Binder与其他进程进行通信了。看到这里我们知道RuntimeInit.java的nativeZygoteInit函数主要是用来启动Binder线程池的。
2.进入SystemServer的main方法
我们再回到RuntimeInit.java的代码,在注释2处调用了RuntimeInit的applicationInit方法,代码如下所示:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer746.jpg?sign=1739351505-WzT5bMIWzYIDoUDD4P5v0BK7uvU5prwm-0-c0b342c07d26eb6d4a47aa0bfd8e7554)
在applicationInit方法中主要调用了invokeStaticMain方法:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer747.jpg?sign=1739351505-eNB7qPL16HADz1hx6PiLImCpxsXWZ5pV-0-fe1ece793e1c9799e549b337a41685ae)
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer748.jpg?sign=1739351505-WuaaGlAlLpRd4b2j5z5AxBhrwlYnD4dO-0-6983620c6d2e94ddd66c500e641bc2e5)
注释1处的className为com.android.server.SystemServer,通过反射返回的cl为SystemServer类。在注释2处找到SystemServer中的main方法。在注释3处将找到的main方法传入MethodAndArgsCaller异常中并抛出该异常,捕获MethodAndArgsCaller异常的代码在ZygoteInit.java的main方法中,这个main方法会调用SystemServer的main方法。那么为什么不直接在invokeStaticMain方法中调用SystemServer的main方法呢?原因是这种抛出异常的处理会清除所有的设置过程需要的堆栈帧,并让SystemServer的main方法看起来像是SystemServer进程的入口方法。在Zygote启动了SystemServer进程后,SystemServer进程已经做了很多的准备工作,而这些工作都是在SystemServer的main方法调用之前做的,这使得SystemServer的main方法看起来不像是SystemServer进程的入口方法,而这种抛出异常交由ZygoteInit.java的main方法来处理,会让SystemServer的main方法看起来像是SystemServer进程的入口方法。
下面来查看在ZygoteInit.java的main方法中是如何捕获MethodAndArgsCaller异常的:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer749.jpg?sign=1739351505-TjmUmPRlp0XskUujFIEmkmJWVLawqIoa-0-b085caa32b81db6c1ab3eccbde3cf3c7)
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer750.jpg?sign=1739351505-xwfwEtMvbbsOCsY5XNvwiCF6RMvORmdd-0-99ed4c55edba772a61a62796fb1657d2)
当捕获到MethodAndArgsCaller异常时就会在注释1处调用MethodAndArgsCaller的run方法,MethodAndArgsCaller是Zygote.java的静态内部类:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer751.jpg?sign=1739351505-N2qbesh2o5Sz0maHEKgDIIeSBBaCsZOE-0-b0fedb19ed4205c3dc28c2dbf23e5974)
注释1处的mMethod指的就是SystemServer的main方法,调用了mMethod的invoke方法后,SystemServer的main方法就会被动态调用,SystemServer 进程就进入了SystemServer的main方法中。
2.3.2 解析SystemServer进程
下面来查看SystemServer的main方法:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer752.jpg?sign=1739351505-iGScc968ZqvzDLvCgHm6IQEcpUX5Iwh5-0-a8241413e1a62572225753ebfabaa1a3)
main方法中只调用了SystemServer的run方法,如下所示:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer753.jpg?sign=1739351505-oEeryYTSsaWgfRQ0udRaKbQR9MS3TenA-0-897ab10a60a10531b79d5b072ad9bc05)
在注释1处加载了动态库libandroid_servers.so。接下来在注释2处创建SystemServiceManager,它会对系统服务进行创建、启动和生命周期管理。在注释3处的startBootstrapServices方法中用SystemServiceManager启动了ActivityManagerService、PowerManagerService、PackageManagerService等服务。在注释4处的startCoreServices方法中则启动了DropBoxManagerService、BatteryService、UsageStatsService和WebViewUpdateService。在注释5处的startOtherServices 方法中启动了CameraService、AlarmManagerService、VrManagerService等服务。这些服务的父类均为SystemService。从注释3、4、5的方法中可以看出,官方把系统服务分为了三种类型,分别是引导服务、核心服务和其他服务,其中其他服务是一些非紧要和不需要立即启动的服务。这些系统服务总共有100多个,表2-1列出部分系统服务及其作用。
表2-1 部分系统服务及其作用
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer754.jpg?sign=1739351505-EirSw3nwaYx5wdQLnxxzOzGbAWjJr16v-0-7a5cc3b4d6a057f553c5f60288bafd7e)
这些系统服务启动逻辑是相似的,这里以启动PowerManagerService来进行举例,代码如下所示:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer755.jpg?sign=1739351505-JrpSKiNHNsY1OKoHh6R87stibDPQOFab-0-36eb7bec43eebd52baff3adfd85ad796)
SystemServiceManager的startService方法启动了PowerManagerService,startService方法如下所示:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer756.jpg?sign=1739351505-fVJqwo1nk9pWGgnef5gLImuHIXlkgyHm-0-7387c6296852761c2f31560e9ab13024)
在注释1处将PowerManagerService添加到mServices中,其中mServices是一个存储SystemService类型的ArrayList,这样就完成了PowerManagerService的注册工作。在注释2处调用PowerManagerService的onStart函数完成启动PowerManagerService。
除了用mSystemServiceManager的startService函数来启动系统服务外,也可以通过如下形式来启动系统服务,以PackageManagerService为例:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer757.jpg?sign=1739351505-bfNMz7E0cMCAigyKOKwAJKOD7kWEACew-0-aa07d10753a6062a80f782eb20a20ffd)
直接调用了PackageManagerService的main方法:
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer758.jpg?sign=1739351505-Rup6leuSZ7gTjn5S4ISZJBlbHBy9yYNh-0-f61faf92d38897f19cf0a4e2b48c1009)
![](https://epubservercos.yuewen.com/D63A94/16896237205618706/epubprivate/OEBPS/Images/figer759.jpg?sign=1739351505-GAxxqXqWc1z5AJZZUgWxGu4Yyed5grqB-0-53401104fdcc6c7b3a25f305d7c4cab0)
在注释1处直接创建PackageManagerService 并在注释2处将PackageManagerService注册到ServiceManager中,ServiceManager用来管理系统中的各种Service,用于系统C/S架构中的Binder通信机制:Client端要使用某个Service,则需要先到ServiceManager查询Service的相关信息,然后根据Service的相关信息与Service所在的Server进程建立通信通路,这样Client端就可以使用Service了。
2.3.3 SystemServer进程总结
SystemServer进程被创建后,主要做了如下工作:
(1)启动Binder线程池,这样就可以与其他进程进行通信。
(2)创建SystemServiceManager,其用于对系统的服务进行创建、启动和生命周期管理。
(3)启动各种系统服务。