玩转Android Framework:System Server

本文将介绍有关Android System Server相关的一些知识。

系统版本: Ubuntu 22.04 lts

AOSP分支: android-14.0.0_r28

在阅读本篇建议先阅读:

Zygote

juejin.cn/post/734457...
Linux fork概念

juejin.cn/post/691261...

本篇依旧会只展示关键代码,所以最好打开AOSP源码一步步的跟着看,才能理解整个的流程。

什么是System Server

在Android的应用层开发中,我们会使用到一系列的service,比如ActivityManagerServicePowerManagerService等,System Server的作用,就是去启动这些Service。

System Server进程启动分析

我们的System Server是从Zygote进程中fork出来的,下面,我就将一步步讲解Zygote启动System Server的整个流程。

首先,我们打开/frameworks/base/core/java/com/android/internal/os/ZygoteInit,找到它的main方法,然后可以找到如下代码:

这里,就是我们System Server启动的关键部分,从代码中我们可以得知,只有startSystemServer这个变量为true的时候,执行我们启动System Server的逻辑,在往上,我们可以看到:

这个变量的值,是由外部参数决定的,这个参数其实在我们的Zygote启动的时候,就已经传进来了,可以打开/system/core/rootdir/init.zygote64.rc,可以看到对应的参数:

那么forkSystemServer这个方法究竟是做什么的,其实从名字上就可以判断出来,这个方法就是从Zygote去fork出我们的System Server的进程的。

首先进入这个方法,其它的先不管,找到这段代码:

再进入Zygote类的forkSystemServer方法:

就可以看到实际上我们是通过Native层去fork我们的进程的,打开/frameworks/base/core/jni/com_android_internal_os_Zygote.cpp,找到com_android_internal_os_Zygote_nativeForkSystemServer,这就是我们的Native层的实际调用。

然后在这个方法里面,我们可以看到它调用了zygoteForkCommon方法:

再进入这个方法,在中间我们就可以找到fork的调用了:

到这一步,其实我们的System Server进程就已经fork出来了,但问题是目前这个进程还没有我们System Server相关的内容,那么接下来,我们就要开始真正启动我们的System Server了。

System Server! 启动!

打开/frameworks/base/core/java/com/android/internal/os/ZygoteInit,继续看它的forkSystemServer方法,首先我们看这一部分:

从注释里面我们也能看出来,这是System Server的启动参数,比如--nice-name=system_server,这个其实就是进程名,com.android.server.SystemServer,其实就是我们的启动类了。

再往下看,可以看到这部分代码:

从刚才我们就已经知道,Zygote.forkSystemServer,是帮我们fork进程的,那么下面这段代码,只有子进程,也就是我们刚刚fork出来的System Server才会执行,如果不明白这部分逻辑的,可以看下开头的fork相关概念。

那我们看下这段代码,首先,System Server进程做了一个判断,如果有32位的Secondary Zygote,那么就等待,等待Secondary Zygote启动之后再进行下一步,接着,就关闭了本进程的zygoteServer,因为被fork出来的System Server子进程不需要通过LocalSocketfork应用进程,再然后,会调用handleSystemServerProcess这个方法:

然后我们直接看这段代码,然后再依次进入ZygoteInit.zygoteInitRuntimeInit.applicationInitfindStaticMain:

最后,在findStaticMain中,找到这部分代码:

可以看到,这就是我们最终返回的Runnable了,那么这个类主要是做什么的呢? 其实就是执行我们传给他的startClassmain方法:

最后这个Runnable的执行,可以在/frameworks/base/core/java/com/android/internal/os/ZygoteInitmain方法里面,forkSystemServer调用的后面找到:

在注释里我们也可以看到,这部分代码是由system_server,也就是Zygotefork出来的System Server进程,去执行的。

那么接下来,我们就要看看我们的com.android.server.SystemServermain方法,看看它到底做了什么。

System Server启动其它服务

打开/frameworks/base/services/java/com/android/server/SystemServer.java,找到它的main方法,可以看到他就是调用了自己这个类的run:

我们再进入run方法:

找到如下的代码块:

这里,就可以看到我们启动服务的地方了,可以看到,服务被分为了4类:BootstrapServicesCoreServicesOtherServicesApexServices,比如我们熟悉的ActivityManagerService,他就被放在了startBootstrapServices中启动。

然后我们回到刚才run方法的最后,可以看到在这里,System Server进入了loop状态,而所有的这些Service就都会运行在system_server这个进程里面了。

打开adb shell,输入ps -A | grep system_server,就可以看到我们的System Server进程了:

到这里,我们就完成了整个System Server的启动分析,和它启动其它Service的分析,那么接下来,我们就要去看看,我们的Launcher是如何启动的了。

相关推荐
2501_916008894 小时前
Web 前端开发常用工具推荐与团队实践分享
android·前端·ios·小程序·uni-app·iphone·webview
我科绝伦(Huanhuan Zhou)5 小时前
MySQL一键升级脚本(5.7-8.0)
android·mysql·adb
怪兽20146 小时前
Android View, SurfaceView, GLSurfaceView 的区别
android·面试
龚礼鹏7 小时前
android 图像显示框架二——流程分析
android
消失的旧时光-19437 小时前
kmp需要技能
android·设计模式·kotlin
帅得不敢出门8 小时前
Linux服务器编译android报no space left on device导致失败的定位解决
android·linux·服务器
雨白8 小时前
协程间的通信管道 —— Kotlin Channel 详解
android·kotlin
TimeFine10 小时前
kotlin协程 容易被忽视的CompletableDeferred
android
czhc114007566311 小时前
Linux1023 mysql 修改密码等
android·mysql·adb
GOATLong12 小时前
MySQL内置函数
android·数据库·c++·vscode·mysql