拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Android 系统层扫盲 07:SystemServer 到底是什么?AMS、WMS、PMS 为什么都从这里启动?

上一篇我们已经把 Zygote 串起来了init ↓ Zygote ↓ 预加载 ART / Framework ↓ fork ↓ system_server我们也知道Zygote Android Java/ART 进程工厂那么接下来问题来了Zygote fork 出system_server以后Android 系统到底怎么继续启动以及我们一直听到的AMS WMS PMS ATMS PowerManagerService DisplayManagerService ...这些服务到底从哪里来的答案就要进入SystemServer这一篇的目标就是搞懂system_server 是什么SystemServer 又是什么以及 Android 大量核心 Framework Service 是怎么被启动起来的。一、先把两个非常容易混的名字分开以后学习 Framework一定会频繁遇到system_server和SystemServer它们不是一个东西。system_server是Linux Process也就是一个进程。可以理解进程名 system_server里面运行着大量 Android Framework 核心系统服务。SystemServer是Java Class源码大致位于frameworks/base/services/java/com/android/server/SystemServer.java它负责在 system_server 进程中初始化 Android Framework 环境并启动大量核心 System Service。所以关系是system_server 进程 SystemServer 这个进程里非常重要的启动入口类这个一定要先分清。二、system_server 是谁创建的上一篇已经讲过Zygote启动以后会执行forkSystemServer()然后Zygote │ │ fork ↓ system_server子进程接着进入com.android.server.SystemServer也就是SystemServer.main()所以init ↓ Zygote ↓ fork ↓ system_server ↓ SystemServer.main()这条链现在应该非常熟悉了。三、为什么 system_server 也要从 Zygote fork因为 system_server 里面运行的大量 Android Framework 代码本身也是Java / ART世界。例如ActivityManagerService WindowManagerService PackageManagerService PowerManagerService等。它们同样需要ART Java 基础类 Android Framework而这些东西 Zygote 已经提前准备好了。所以Zygote ↓ fork ↓ system_server非常自然。它和普通 App Process 的共同点是都是在 Zygote 已经准备好的 ART / Framework 环境基础上创建出来的。区别则是普通 App Process ↓ 运行 App system_server ↓ 运行 Android Framework 核心系统服务四、system_server 到底有多重要可以先把 Android 想成一个城市。普通 App微信 地图 支付宝 自己的 App像城市里的居民和企业。而 system_server 里面的大量系统服务则更像公安 住建 户籍 电力 交通管理它们负责整个 Android 世界的公共管理。例如AMS ↓ 进程 / 组件等系统管理 ATMS ↓ Activity / Task 管理 WMS ↓ Window 管理 PMS ↓ Package 管理 PowerManagerService ↓ 电源管理所以可以先简单理解system_server 是 Android Framework 管理体系的大本营。五、没有 system_server 会发生什么假设Kernel init Zygote都起来了。但system_server没有正常启动。那很多 Android 核心能力都不存在Activity 谁管理 App 进程谁管理 窗口谁管理 APK 谁管理 权限相关系统能力谁协调 电源谁管理 输入谁管理也就是说Linux 底层可能还活着但我们熟悉的 Android Framework 基本没有真正建立起来。所以Kernel 启动 Linux 地基起来了 system_server System Services 启动 Android Framework 真正开始活起来六、SystemServer.main() 做什么进入SystemServer.main()以后会创建SystemServer并进入它的主运行流程。第一阶段不需要跟源码。只需要知道它会做几类非常重要的事情准备 system_server 主线程环境 准备 Looper 加载部分 Native Library 创建 System Context 创建 SystemServiceManager 启动大量 System Service 进入主线程 Looper当前 AOSP 的 SystemServer 启动过程中仍然会初始化主 Looper、加载android_serversNative Library、创建 System Context 和 SystemServiceManager然后进入系统服务启动阶段。所以可以粗略画成SystemServer.main() ↓ 初始化 system_server ↓ 创建系统 Context ↓ 准备 SystemServiceManager ↓ 启动大量系统服务 ↓ Looper.loop() ↓ system_server 长期运行七、为什么 system_server 也需要 Looper这个 App 开发者就很好理解了。我们平时知道Android Main Thread ↓ Looper ↓ MessageQueue ↓ Handler而system_server本身也是一个长期运行的 Android Java 进程。它同样需要Looper MessageQueue Handler去处理大量系统消息和回调。所以当前 SystemServer 启动完成以后最终也会Looper.loop();进入长期运行状态。这意味着SystemServer 不是把 AMS、WMS 启动完以后自己就结束了。而是system_server 会一直活着。八、System Context 又是什么SystemServer 启动过程中会创建System Context当前源码中可以看到ActivityThread.systemMain() ↓ getSystemContext()这套初始化。App 开发者看到Context应该非常熟。普通 App 有Activity Context Application Context而 system_server 也需要一个系统级 Context用来访问Resources PackageManager ContentResolver System Service 系统配置等能力。你现在只需要知道SystemServer 本身也生活在 Android Framework 世界里所以它同样需要 Context。九、接下来出现一个非常重要的类SystemServiceManagerSystemServer 初始化过程中会创建SystemServiceManager当前 AOSP 仍然明确创建new SystemServiceManager(mSystemContext)并注册到 LocalServices 中。这个名字第一次看特别容易和ServiceManager搞混。注意SystemServiceManager和ServiceManager不是一个东西。我们后面专门区分。十、SystemServiceManager 是干嘛的先按名字理解System Service Manager它主要负责system_server 内 SystemService 的启动和生命周期管理。例如以后会看到mSystemServiceManager.startService( BatteryService.class );或者mSystemServiceManager.startBootPhase(...)所以可以粗略理解SystemServer ↓ SystemServiceManager ↓ 启动 / 管理各种 SystemService有点像SystemServer 的系统服务启动管家。十一、为什么还需要 SystemServiceManager如果所有服务都这样new ServiceA(); new ServiceB(); new ServiceC(); new ServiceD();随着 Android 系统越来越复杂几百个系统组件 各种依赖 各种启动阶段 各种生命周期管理就会越来越乱。所以 Android 抽象出SystemService以及SystemServiceManager来统一管理很多服务的创建 启动 Boot Phase 用户切换 生命周期等等。第一阶段知道它是 system_server 内部服务生命周期的重要管理者。就够了。十二、SystemServer 开始批量启动系统服务这就是这一篇最核心的部分。传统 Android Framework 教程经常会看到startBootstrapServices() startCoreServices() startOtherServices()当前 AOSP HEAD 已经是startBootstrapServices() startCoreServices() startOtherServices() startApexServices()也就是说现代 AOSP 还增加了 APEX 中定义的 System Service 启动阶段。所以当前可以画成SystemServer │ ├── startBootstrapServices() │ ├── startCoreServices() │ ├── startOtherServices() │ └── startApexServices()十三、为什么不能所有 Service 一起启动因为它们存在依赖关系例如Service B 需要 Service A Service C 又需要 Service B如果C 比 B 先启动可能直接报错。所以 SystemServer 启动 Service 是有顺序的。例如当前源码里就存在大量类似PowerManager 要尽早启动 PackageManager 前要先准备其他依赖 SensorService 又依赖 PackageManager 等服务这样的顺序要求。所以SystemServer 不是简单把所有 Service new 一遍而是在建立一张有依赖关系的系统服务网络。十四、Bootstrap Services 是什么Bootstrap可以理解启动系统最基础的一批服务。当前 AOSP 对startBootstrapServices()的源码注释非常直接这里启动的是让系统“站起来”所必需的一组关键服务而且这些服务之间存在复杂的相互依赖。里面会涉及一些非常核心的东西。例如ActivityManagerService PackageManagerService PowerManagerService DisplayManagerService UserManager 等相关能力不同 Android 版本具体组织会变化。现在只需要理解Bootstrap Android Framework 最基础、最早需要的一批核心服务。十五、AMS 就在这里出现了我们一直提到AMS全称ActivityManagerService当前 SystemServer 的 Bootstrap 启动流程中会通过ActivityManagerService.Lifecycle.startService(...)启动 AMS并把 SystemServiceManager 等依赖交给它。所以关系开始变成SystemServer ↓ startBootstrapServices() ↓ ActivityManagerServiceAMS 后面会成为Android Framework 最核心的系统服务之一。后面第九篇我们会再讲它到底负责什么。十六、PMS 也在早期启动另一个非常核心的PMS全称PackageManagerService也在早期启动流程中。当前 AOSP 可以看到PackageManagerService.main(...)由 SystemServer 启动。PMS 为什么必须很早启动因为 Android 后面做很多事情都需要知道系统安装了哪些 Package 某个 Activity 属于哪个 App App UID 是多少 权限声明是什么 Intent 应该匹配哪个组件这些都离不开 Package 系统。所以PMS本质上是 Android 系统非常基础的应用包数据库 包管理中心。十七、Core Services 又是什么接下来startCoreServices()源码自己的描述是启动一些很重要、但没有深度缠绕在 Bootstrap 依赖关系中的核心服务。当前这里可以看到例如SystemConfigService BatteryService UsageStatsService WebViewUpdateService ...等。所以可以粗略理解Bootstrap Services 系统先站起来必须有的 Core Services Android 核心能力继续补齐十八、Other Services 是什么然后来到startOtherServices()这个函数通常非常大。里面会继续启动大量 Android 系统功能。当前源码中就可以看到WindowManagerService InputManagerService 网络相关服务 Telephony 相关服务 AlarmManager 相关服务 Camera 代理服务 SystemUI 启动 ...等大量内容。所以Other Services这个名字虽然听起来像“不重要的其他服务”。但实际上里面有大量我们每天使用的关键 Android 能力。十九、WMS 就在这里出现例如非常重要的WMS全称WindowManagerService当前 SystemServer 里仍然能看到类似WindowManagerService.main(...)然后ServiceManager.addService( Context.WINDOW_SERVICE, wm )把 WMS 注册进去。所以SystemServer ↓ startOtherServices() ↓ WindowManagerServiceWMS 以后负责Window 窗口层级 窗口布局 显示区域 和 Input / Display 等系统协作等大量能力。二十、InputManagerService 也在附近WMS 和InputManagerService关系非常紧密。因为 Android Window 不只是显示出来。还需要处理Touch Keyboard Mouse 按键等输入。所以在 SystemServer 启动流程里InputManagerService和WindowManagerService也会按照明确顺序初始化。这里已经能看出系统服务不是一个个完全独立的孤岛。它们之间有大量协作。二十一、现代 Android 还有 startApexServices()如果看一些比较老的 Framework 教程通常只会看到startBootstrapServices() startCoreServices() startOtherServices()但当前 AOSP HEAD 中还有startApexServices()它用于启动定义在APEX模块中的 System Service。而且当前源码明确要求APEX Services 必须最后启动之后不能再继续启动其他 System Service。这个第一阶段不用深入。只需要知道Android Framework 也在不断模块化系统服务启动体系也随着现代 Android 演进。二十二、为什么现在越来越多东西被模块化过去很多 Android 核心能力跟整个 system image 绑定得非常紧系统升级才能更新。现代 Android 越来越强调Mainline APEX 模块化更新所以某些系统能力可以独立于整套 OTA 更新。这就是startApexServices()逐渐出现在现代 SystemServer 启动流程里的背景之一。第一阶段不用继续展开 APEX。二十三、这里必须区分 SystemServiceManager 和 ServiceManager这一块特别容易乱。先看SystemServiceManager它主要关注System Service 的创建和生命周期。例如startService() startBootPhase()可以粗略理解谁负责“把服务启动起来”。而ServiceManager是另外一个东西。它主要和Binder Service 注册 / 查找密切相关。可以粗略理解谁负责“让其他进程能够找到这个 Binder Service”。二十四、用 WMS 举例最好理解SystemServer 创建 WMSWindowManagerService.main(...)得到wm这个服务对象。但是App 怎么找到它于是会ServiceManager.addService( Context.WINDOW_SERVICE, wm );意思可以先理解成ServiceManager 你好 我这里有一个 Binder Service 名字叫 window 对象是 WMS 帮我登记一下这样其他进程才能通过系统 Binder 体系找到它。当前 AOSP 的 WMS 启动路径仍然明确执行这一步。二十五、所以一个 Service 可以经历两件事你可以把它理解成第一步 SystemServer / SystemServiceManager ↓ 把 Service 创建并启动起来然后第二步 ServiceManager ↓ 把 Binder Service 注册到系统 ↓ 让别人能找到当然不同 Service 的实际启动方式不完全一样。有些使用SystemServiceManager.startService()有些是历史遗留或者特殊 ServiceService.main()再ServiceManager.addService()所以不要死记成所有系统服务完全同一种写法。二十六、ServiceManager 可以先想成“Binder 电话簿”这个比喻很好用。假设system_server里面有WMS AMS 其他 Binder Service其他进程怎么知道它们在哪里可以想象ServiceManager 系统 Binder 服务电话簿服务注册WMS ↓ ServiceManager.addService(window, WMS)客户端查询我要 window Service ↓ ServiceManager ↓ 找到 WMS Binder之后App ↓ Binder ↓ WMS就能通信。第八篇 Binder 会把这一套真正展开。二十七、这和我们 App 开发的 getSystemService 有什么关系现在开始和普通 App 开发连接。我们写val manager getSystemService(Context.POWER_SERVICE)拿到PowerManager或者getSystemService(Context.ACTIVITY_SERVICE)拿到ActivityManager以前我们觉得getSystemService() ↓ Android 给我一个 Manager现在开始知道背后可能是App ↓ Framework Manager ↓ Binder ↓ system_server ↓ 某个 System Service也就是说Manager 很多时候只是 App 进程这一侧的 Framework 封装。真正系统级管理工作往往发生在 system_server 里的 Service 中。二十八、比如 PowerManagerAppPowerManager属于Framework API / Manager系统侧PowerManagerService属于System Service可以粗略理解App Process PowerManager │ │ Binder ↓ system_server PowerManagerService所以现在你应该越来越能理解Manager 和 ManagerService 为什么老是成对出现。二十九、但不是所有 System Service 都必须在 system_server这点一定要注意。不要形成错误认识Android 所有系统服务都运行在 system_server。不是。Android 官方当前架构文档列出的系统服务还包括SurfaceFlinger MediaService等它们并不等于 system_server 里的 Java Service。例如SurfaceFlinger是独立的 Native 系统进程。所以更准确的说法system_server 承载了大量非常重要的 Java Framework System Service但 Android 还有很多独立 Native Service / 系统进程。三十、为什么很多 Service 要放进同一个 system_server这有很多工程原因。第一阶段可以理解几个明显好处大量 Framework Service 可以共享运行环境 Service 之间内部协作方便 减少大量独立 Java Runtime 进程 统一启动和生命周期管理 统一系统级权限环境如果AMS 一个进程 PMS 一个进程 WMS 一个进程 PowerManagerService 一个进程 DisplayManagerService 一个进程整个 Android 系统会增加大量进程 ART Runtime IPC 启动管理 内存开销所以很多高度相关的 Framework Service 放在system_server这个核心进程中统一运行。三十一、但是放在一起也有风险好处明显。风险也明显system_server 太重要了。因为AMS WMS PMS Power Display ...大量核心服务都在这个进程中。如果 system_server 出现严重死锁 主线程卡死 Native Crash 不可恢复异常影响就不是某个普通 App 崩了。而可能是Android Framework 核心体系出问题。三十二、所以 SystemServer 很早就启动 Watchdog当前 AOSP 的 Bootstrap Services 启动阶段会很早启动Watchdog源码甚至明确解释尽可能早启动 Watchdog以便如果 system_server 在早期启动过程中死锁可以处理这种严重问题。所以Watchdog可以先理解system_server 的重要“看门狗”。它会监控一些严重卡死问题。以后学习System Server Watchdog时再展开。三十三、System Service 还有“启动阶段”Android 系统不是Service 启动 立即拥有全部能力很多 Service 会随着系统启动进入不同Boot Phase例如系统刚启动 核心服务准备 System Services Ready 设备特定服务 Ready ActivityManager Ready Boot Completed不同阶段。SystemServiceManager 会通过类似startBootPhase(...)通知各个 SystemService系统现在已经进入新的启动阶段了。当前 WMS 启动附近就能看到 SystemServiceManager 推进到特定 Boot Phase 后再继续后续服务初始化。三十四、为什么需要 Boot Phase假设 Service A启动得比较早但它需要PackageManager 已经准备完成才能执行某些工作。那不能构造函数里直接干因为此时 PMS 可能还没 Ready。所以可以Service A 先创建 ↓ 等待系统进入某个 Boot Phase ↓ 再开始需要 PMS 的初始化这样 Android 就可以协调大量服务之间复杂的启动依赖。三十五、所以 Service 启动不是一个瞬间动作以后看源码不要简单理解startService() ↓ Service 彻底 Ready实际可能是构造 Service ↓ onStart() ↓ 注册 Binder ↓ 等待 Boot Phase ↓ onBootPhase() ↓ 系统 Ready ↓ 用户解锁后继续初始化 ...这已经属于第二阶段源码学习的内容。现在只知道Android System Service 有生命周期和启动阶段。就够了。三十六、SystemUI 又在哪里这里顺便解决一个很容易混的问题。SystemUI虽然名字里面有System但它并不是system_server 里一个普通 Java ServiceSystemUI 是一个独立系统组件 / 进程。当前 SystemServer 的startOtherServices()后期仍然会执行startSystemUi(...)来启动 SystemUI。所以SystemServer ↓ 可以负责启动 SystemUI但SystemUI ≠ 运行在 system_server 里面这一点不要混。三十七、Launcher 又什么时候出现上一篇我们讲过System Services Ready ↓ AMS / ATMS ↓ 启动 Home ↓ Launcher所以 SystemServer 的任务不是“直接 new 一个 Launcher”。它的任务是把 Framework System Service 建起来等AMS ATMS PMS WMS等核心服务逐步 ReadyAndroid 已经具备正常运行 App 的条件之后再通过 Activity 管理体系启动Home / Launcher三十八、现在整个 Android 开机流程可以升级了上一篇只是Zygote ↓ system_server ↓ System Services ↓ Launcher现在可以展开成Zygote ↓ fork ↓ system_server ↓ SystemServer.main() ↓ 准备 System Context ↓ 创建 SystemServiceManager ↓ startBootstrapServices() │ ├── AMS ├── PMS ├── Power... │ ↓ startCoreServices() │ ├── Battery ├── UsageStats └── ... ↓ startOtherServices() │ ├── WMS ├── Input ├── Network ├── SystemUI └── ... ↓ startApexServices() ↓ System Ready ↓ 启动 Launcher这条链比第五篇已经清晰很多了。三十九、再和 Binder 串一下system_server 最大的意义之一就是它里面的服务需要被其他进程调用。例如App Process想调用 WMS。但App Process和system_server不是一个进程。所以App ↓ WindowManager ↓ Binder ↓ WindowManagerService ↓ system_server这就是为什么下一篇Binder必须出现。因为SystemServer 把一堆 Service 启起来只是第一步真正关键的是其他进程怎么调用这些 ServiceBinder 就是答案。四十、从 App 开发视角重新理解 getSystemService()我们以前val powerManager getSystemService(PowerManager::class.java)只看到拿到 PowerManager现在看到的是App Process │ ↓ Framework Manager │ ↓ Binder Proxy │ │ IPC ↓ system_server │ ↓ System Service所以getSystemService() 并不是简单从一个 Map 里拿个普通 Java 对象然后所有工作都在 App 本地执行。很多 Manager 背后真正连接的是system_server里的 Binder Service。四十一、SystemServer 其实就是 Framework 的“开机入口”我们现在已经可以给 SystemServer 一个非常好的定位Zygote Android Java/ART 进程底座SystemServer Android Framework 系统服务的启动入口SystemServer 负责把AMS PMS WMS Power Display Input Network ...一个个建立起来。所以如果第五篇讲的是 Android 整个系统怎么开机那么 SystemServer 可以看成 Framework 世界自己的“开机程序”。这个理解非常好用。四十二、源码以后从哪里看以后第二阶段真正开始跟源码可以从frameworks/base/services/java/com/android/server/SystemServer.java开始。重点找main() run() startBootstrapServices() startCoreServices() startOtherServices() startApexServices()然后再顺着进入ActivityManagerService PackageManagerService WindowManagerService SystemServiceManager即可。当前 AOSP HEAD 的 SystemServer 主启动流程仍然明确依次调用这四类 Service 启动函数。现在不要进去啃。四十三、第一阶段你只需要回答这几个问题system_server 是什么承载大量 Android Framework 核心系统服务的 Linux 进程SystemServer 是什么system_server 中负责初始化并启动 Framework System Service 的核心 Java 类谁创建 system_serverZygote forkAMS / PMS / WMS 从哪里起来SystemServer 启动流程SystemServiceManager 干嘛负责很多 SystemService 的启动和生命周期管理ServiceManager 干嘛负责 Binder Service 注册和查找system_server 是不是包含所有 Android 系统服务不是 SurfaceFlinger 等很多 Native Service 是独立进程这几个问题会回答第七篇就已经完成。四十四、最终把 Zygote 和 SystemServer 串起来现在从第五篇到第七篇已经可以形成init ↓ 启动 Zygote ↓ Zygote 预加载 ART / Framework ↓ fork system_server ↓ SystemServer.main() ↓ 创建 SystemServiceManager ↓ 启动 AMS / PMS / WMS / ... ↓ 注册各种 Binder Service ↓ Framework System Services Ready ↓ 可以正常管理 App ↓ 启动 LauncherAndroid Framework 就这样真正建立起来了。四十五、一句话总结如果Zygote是Android Java/ART 进程工厂。那么SystemServer就是Android Framework 系统服务启动中心。而system_server就是承载这些核心 Framework Service 的 Linux 进程。最终记住Zygote ↓ fork ↓ system_server ↓ SystemServer ↓ SystemServiceManager ↓ AMS / PMS / WMS / ...SystemServer 把这些 Service 启起来以后Android Framework 才真正具备管理 App 管理 Activity 管理 Package 管理 Window 管理 Power 管理 Input等核心能力。第七篇到这里system_server和 SystemServer 的主线已经建立起来了。接下来先不急着直接进入 Binder。因为现在我们已经遇到了一个非常关键的问题App Process PowerManager │ │ ??? ↓ system_server PowerManagerServicePowerManager和PowerManagerService明明运行在两个不同的 Linux Process 中那 App 到底怎么像调用普通接口一样调用另一个进程里的 System Service在正式学习 Binder 之前我们先插入一篇番外《Android 系统层扫盲番外从 Interface、Contract 到 AIDL一步看懂 Binder 的接口设计思想》我们会从 App 开发里最熟悉的Interface ↓ Impl一步一步升级到Contract ↓ 模块边界 ↓ Proxy ↓ 进程边界 ↓ Stub ↓ AIDL重点搞清楚为什么普通接口跨进程以后不能直接调用为什么会自然出现 Proxy 和 StubAIDL 和我们平时写的 Contract本质上到底有什么联系等这篇番外把“为什么需要跨进程接口”讲清楚以后第八篇再正式进入《Android 系统层扫盲 08Binder 到底怎么跨进程从 PowerManager 一路跑到 system_server》到时候我们再真正看PowerManager ↓ IPowerManager.Proxy ↓ Parcel ↓ Binder Driver ↓ IPowerManager.Stub ↓ PowerManagerService也就是先理解设计思想再理解 Android 是怎么把这套思想真正落到 Binder 和 Linux Kernel 上的。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门