这一次,让SystemServer, SystemServiceManager,SystemService不可能再记混

近期整理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方法

相关推荐
橙子199110161 小时前
Kotlin 中的作用域函数
android·开发语言·kotlin
zimoyin1 小时前
Kotlin 懒初始化值
android·开发语言·kotlin
枣伊吕波2 小时前
第六节第二部分:抽象类的应用-模板方法设计模式
android·java·设计模式
萧然CS2 小时前
使用ADB命令操作Android的apk/aab包
android·adb
_extraordinary_6 小时前
MySQL 事务(二)
android·数据库·mysql
鸿蒙布道师10 小时前
鸿蒙NEXT开发动画案例5
android·ios·华为·harmonyos·鸿蒙系统·arkui·huawei
橙子1991101615 小时前
在 Kotlin 中什么是委托属性,简要说说其使用场景和原理
android·开发语言·kotlin
androidwork15 小时前
Kotlin Android LeakCanary内存泄漏检测实战
android·开发语言·kotlin
笨鸭先游16 小时前
Android Studio的jks文件
android·ide·android studio
gys989516 小时前
android studio开发aar插件,并用uniapp开发APP使用这个aar
android·uni-app·android studio