近期整理android runtime的时候,看到以前在印象笔记里记的SystemServer跟SystemServiceManager笔记,查看源码的时候都避不开SystemServer跟SystemServiceManager,笔记尘封已久,之前一直犹豫会不会做得不够全面详细,毕竟现在客户端研发也到了末法时代,改改笔记结构内容发出来让大佬们指正一下也好.
场景复现
"SystemServer是什么, look at my eyes!"

"是android系统里的一个进程"
"什么进程"
"由Zygote进程孵化的第一个进程,在ZygoteInit类在执行main方法的过程中体现,具体forkSystemService方法"
"不是第一个进程不是launcher进程吗?桌面呀"
"不是,那个是app进程"
"那SystemServiceManager呢"
"从来不是同个东西"
"管理SystemService吗,还是管理SystemServer"
"大哥你别捣乱了,本来不晕都被你绕晕了"
"......,要不你还是好好说下吧"
SystemServer
进程怎么被创建的
从ZygoteInit方法的main方法可知,当参数argv里,携带允许start-system-server
参数时,会触发forkSystemServer方法,内部通过拼接SystemServer进程所需参数后,转化为ZygoteCommand,最终借助Zygote类的同名方法,完成SystemServer进程的创建,最终返回子进程pid给到Zygote进程,代码执行回到ZygoteInit.随后执行handleSystemServerProcess
方法处让SystemServer进程处理其他内容.



来,这里Zygote怎么创建SystemServer的,我们点击forkSystemServer
方法查看内容.好的,native方法,看不下去了.收!

创建进程时都干了什么
看main方法,创建了一个SystemServer对象并执行其run方法.
run方法,这是个Runable
?还真不是,实现的是Dumpable
接口

但是这个接口里也没有对run抽象方法的声明呀.为什么,为什么?为什么!!!
没错,人家压根不是什么抽象方法run,就是起名叫了run而已.

好好好,都这么玩是吧,谷歌工程师们.唔,按我们业内的说法,属于历史原因,咱们就不追究了.如果你知道的话也麻烦告诉我.
回到run方法的流程内容,大概包括如下内容:
- Looper处理
- 加载动态库lib
- 系统级别上下文创建和主线模块初始化
- ActivityThread调用每个进程主线模块初始化
- 创建SystemServiceManager挂载到LocalServices
- SystemServiceManager启动各种服务
- Looper开启循环

Looper初始化
调用了Looper.prepareMainLooper();


从上述代码可以知道,创建的是一个不可退出的Looper.诶?Looper,不是得跟线程绑定的吗,你看,还得存ThreadLocal里面,那目前所在的线程是什么线程? 答:主线程!SystemServer进程的main方法所在线程.
当时我在这里也打了问号:主线程不是UI线程吗?这里还在系统创建阶段,UI线程可能还没创建对吧?
这里要看对主线程的定义,在系统进程中,主线程通常是指进程启动时的第一个线程。对于SystemServer进程,main方法所在的线程就是主线程.但我们在android 应用中的主线程一般说的都是UI线程,这里说法不冲突.
总的作用就是让SystemServer进程的主线程有了Looper,使得主线程能够处理消息和任务。 先讲到这里,下面介绍looper调用loop方法我们再展开介绍.
加载动态库lib
加载android_servers.so
,这个暂时没深挖,以后再说.
基于创建AcitvityThread来完成系统级别上下文创建和主线模块初始化
在这里开始整大活了,ActivityThread对象的创建,就是在SystemServer进程里完成的 ,关于ActivityThread创建的细节,我再单独拎出来介绍.完成创建后获取系统级别的Context.后续所有用到系统服务创建的,基本上都依赖mSystemContext
字段.

调用主线模块中的各种初始器API,什么系统里的大管理对象,都在系统初始化阶段都实例化一遍.
基于系统级别上下文创建SystemServiceManager并挂载到LocalServices
来了,SystemServer的main方法里用new的方式创建了SystemServiceManager,使用LocalServices保存起来,这句记住以后还能记乱的话,那,那,那......那你就回来再看一遍!!!这里先打住,下面介绍SystemServiceManager时再说说保存方式

基于SystemServiceManager启动各种服务
这里包括但不限于:
-
Bootstrap服务: 启动系统启动所需的一小部分关键服务,由于这些服务具有复杂的相互依赖关系,在这里将它们全部初始化。具体查看方法内
mSystemServiceManager.startService
所启动的服务。注意,ActivityManagerService,简称AMS,也是在这个方法内被实例化的 -
核心服务
-
其他服务
looper开启循环
调用loop方法后,SystemServer进程的主线程开始接收消息,消息都是Android标准的Message对象,它们被放入SystemServer主线程的MessageQueue中,由Looper.loop
方法按顺序取出并分发给对应的Handler处理.
但是要接收什么消息?应用消息?系统消息?还是从哪来的Message?
接收消息
- 系统服务内部消息:各种系统服务(如ActivityManagerService、PackageManagerService、WindowManagerService等),通过Handler发送到主线程的消息,这些服务大多在启动时就会创建Handler与主线程的MessageQueue关联,用于服务内部状态更新、跨服务协调等.
- Binder通信消息:应用进程通过Binder机制向系统服务发起的请求,这些请求通常在Binder线程池中接收,然后通过Handler转发到主线程处理.例如:应用启动Activity、Service的请求都会通过这种方式传递
- 延时任务消息:系统服务通过Handler.postDelayed()安排的定时任务,用于处理需要延迟执行的操作
- 事件响应消息:对系统广播、Intent的响应,硬件相关事件(如电源状态变化)的处理
- 内部状态转换消息:服务生命周期状态变化,系统配置变更通知
SystemServer类里使用Looper#looper跟ZygoteInit类里ZygoteServer#runSelectLoop有什么区别?为什么?
这里的消息循环与ZygoteServer
中用于接收新应用启动请求的runSelectLoop
方法是完全不同的机制。
- ZygoteServer使用的是
Socket select
循环来监听应用启动请求 - SystemServer使用的是标准Android
Handler
消息循环机制
因为Zygote进程的作用是等待并处理新应用启动请求,要求高效地接收来自AMS的应用启动请求,快速fork出新进程,也把限制只有特定系统进程可以请求创建应用.所以使用基于Socket I/O的阻塞式监听.简单说就是,需要处理跨进程Socket通信,要求fork要快,还要安全.
但是SystemServer进程作用是管理各种系统服务,响应应用请求和系统事件,尤其是灵活处理各类异步事件,内部服务需要通过Binder提供给应用程序.所以使用基于Handler/Looper的消息驱动模式.简单说就是,需要处理内部服务间的协作,因为内部服务都在同一进程中,消息驱动适合处理大量并发的、轻量级的系统服务请求.
SystemServiceManager
用来干嘛
概括就是管理SystemServer进程内系统服务的创建、启动和其他生命周期事件(在上面截图也能看到各种startService,用它开启了多少系统服务).
怎么被保存的:LocalServices#addService
前面提到在SystemServer的run方法里,会用LocalServices的addService方法完成保存
LocalServices只能在同一个进程中使用(但这里是SystemServer进程内),内部使用静态字段map位置存储添加的服务,在添加删除时候以该map为同步锁,确保线程安全.

SystemServiceManager怎么保存其他服务的:容器
点开源码,列举其内容方法的重载,能得到结论:
-
不管是类名,类的字节码对象都将通过类加载器被转换成
SystemService
对象 执行重载方法 -
调用
SystemService
的抽象方法onStart
开启服务,并以SystemService
对象的形式,记录在列表字段里,用于防止服务重复启动.这里区别于四大组件里Service的onStart
方法
关于SystemSevice
在文章开头故意给大家打岔的内容,我们现在也明确知道,SystemServiceManager确实是管理系统服务,你要说管理一堆SystemSevice也行,因为还真有SystemSevice这个类来代表那些系统服务,附上源码和介绍
补充:
SystemServer类里使用Looper#looper,那处理UI吗?
不处理. SystemServer主要处理系统级别的服务消息,而不是UI相关的消息。
LocalServices#addService除了保存SystemServiceManager,还保存了什么呢?
至少还保存了PermissionMigrationHelperImpl跟AppOpMigrationHelperImpl对象.详见startBootstrapServices
方法