Android 系统技术探索(2)构建大脑(System Services & PMS)

好!既然上一阶段 Zygote 已经成功 Fork 出了 SystemServer 进程,那我们就正式进入第二阶段:构建大脑(System Services & PMS)。 🧠

这一阶段是 Android 启动过程中CPU 负载最高、I/O 最密集的时段,也是我们系统优化工程师最容易"拿分"的地方。因为这里每优化 100ms,用户都能切身感受到开机变快了。

🏛️ Part 1: 原理与流程 ------ SystemServer 的"三步走"

SystemServer 是整个 Android Framework 的载体。它的 main() 方法就像一个精密的指挥官,按照严格的顺序启动几十甚至上百个系统服务。

为了防止服务之间互相依赖导致死锁(比如 AMS 启动依赖 PMS,而 PMS 又依赖 PowerManager),Google 把启动过程分成了三类:

  • Bootstrap Services (引导服务) 🛡️
    • 地位: 系统生死攸关的基础设施。
    • 成员: ActivityManagerService (Lifecycle), PowerManagerService (电源), LightsService (灯光), DisplayManagerService (显示基础).
    • 特点: 这些服务起不来,SystemServer 直接崩,手机无限重启。
  • Core Services (核心服务) 🔋
    • 地位: 必须要在其他乱七八糟服务之前准备好的核心。
    • 成员: 重点是 BatteryService 和 UsageStatsService。
    • 注意: 如果你在做车载系统或定制系统,通常不建议往这里塞东西,除非你非常确定它属于"Core"。
  • Other Services (其他服务) 🧩
    • 地位: 剩下的 80% 都在这里。
    • 成员: CameraService, AudioService, BluetoothService, 以及我们马上要重点谈的 PackageManagerService (PMS) 的后期初始化。
    • SystemReady: 当所有服务都 start 完毕后,AMS 会通知大家 systemReady()。这是一个关键信号,意味着"虽然界面还没出来,但我们已经准备好接受外部请求了"。
      🐢 Part 2: 启动耗时大户 ------ PMS (PackageManagerService)
      如果说 SystemServer 是大脑,那 PMS 就是负责"记忆检索"的海马体。
      在 Zygote 阶段,我们提到了 boot_progress_pms_system_scan_start,这标志着 PMS 开始工作。为什么它慢?
  1. 扫描逻辑 (Scanning) 📂
    PMS 需要遍历 /system/app, /vendor/app, /data/app 等目录下的所有 APK 文件。
  • 解析 AndroidManifest.xml: 读取包名、权限、Activity/Service 定义。
  • 校验签名: 确保应用没有被篡改。
  • 建立缓存: 把解析结果存入 package.xml 和 packages.list,下次开机可以直接读缓存(除非有 OTA 升级或缓存损坏)。
  1. OTA 后的噩梦 (Dexopt) ⚙️
    如果你刚升级完系统,开机特别慢,并在 Logo 处显示"正在优化应用",那就是 PMS 在调用 installd 进行 Dexopt(将 dex 编译成 oat/vdex 机器码)。
  • 原理: Android 10+ 引入了 APEX 和 AOT/JIT 混合编译,虽然减少了全量编译的情况,但在首次开机或大版本升级时,PMS 依然要花费大量时间做这些"体力活"。
    🛠️ Part 3: 实战分析 ------ 如何抓出拖后腿的服务?
    作为系统开发,当 Logcat 里打印出 SystemServer: SystemServer init end 比平时晚了 5 秒,我们该怎么查?
  1. 利用 SystemServerTiming (日志分析) 📜
    SystemServer 在启动每个服务时,都会打一个 SystemServerTiming 的 Tag。
  • 命令: adb logcat -b system | grep "SystemServerTiming"

  • 输出示例:

    I SystemServerTiming: StartPackageManagerService took 150ms

    I SystemServerTiming: StartActivityManagerService took 20ms

    ...

    I SystemServerTiming: StartOemService took 2000ms <-- 凶手找到了!

  • 实战技巧: 写个简单的 Python/Shell 脚本,抓取这些 Log 并自动排序,直接把耗时 Top 5 的服务甩给负责的同事(或者甩给 Vendor 厂商)。

  1. 深度剖析:Perfetto / Systrace (可视化) 📉
    如果 Log 看不出细节(比如某个服务虽然只花了 100ms,但它导致了严重的锁竞争),就要用 Perfetto。
  • 关注点:
    • 在 SystemServer 进程的主线程上,寻找长条的 Slice。
    • Lock Contention (锁竞争): 经常会看到 monitor contention,点进去看 Current Owner 是谁。
    • 案例: 某次我们发现开机慢,Trace 显示 AMS 在等待 PMS 的锁,而 PMS 正在疯狂做 I/O 操作解析一个巨大的预装游戏 APK。
    • 解决方案: 把这个预装游戏的解析放到后台线程,或者利用 Parallel Package Parsing (多线程扫描,Android R+ 已经默认开启) 进行调优。
  1. 各种 "Manager" 的死锁 (Deadlock) 🕸️
    这是开发中自定义 System Service 最容易踩的坑。
  • 场景: Service A 的 onStart 里调用了 Service B 的方法,而 Service B 此时还没注册到 ServiceManager,或者 Service B 的锁被 A 持有。
  • 现象: Watchdog 触发,手机重启。
  • 分析: 必须看 /data/anr/ 下的 Trace 文件,搜索 blocked 状态的线程,画出锁的依赖图。
    💡 一个硬核的思考题
    在 Android 的演进中,Google 为了加速 SystemServer 启动,引入了 SystemServerInitThreadPool。
    这意味着部分服务的初始化可以并行运行,而不是全在主线程串行。
    这就引出了下一阶段的关键:
    当所有服务都准备好后,AMS 会通知 Launcher 启动,这时候屏幕终于要有画面了。但是!如果没有 SurfaceFlinger 和 HWC 的配合,AMS 甚至画不出一个像素。
    关于这一部分(PMS 和 SystemServer),你有没有遇到过那种**"加了一个小功能,结果导致开机变慢或者 SystemServer 起不来"的坑?或者我们直接进入最酷炫的第三阶段:光影魔术(SurfaceFlinger & 图形栈)**? 😎
相关推荐
ji_shuke2 小时前
opencv-mobile 和 ncnn-android 环境配置
android·前端·javascript·人工智能·opencv
sunnyday04264 小时前
Spring Boot 项目中使用 Dynamic Datasource 实现多数据源管理
android·spring boot·后端
幽络源小助理5 小时前
下载安装AndroidStudio配置Gradle运行第一个kotlin程序
android·开发语言·kotlin
inBuilder低代码平台5 小时前
浅谈安卓Webview从初级到高级应用
android·java·webview
豌豆学姐5 小时前
Sora2 短剧视频创作中如何保持人物一致性?角色创建接口教程
android·java·aigc·php·音视频·uniapp
白熊小北极5 小时前
Android Jetpack Compose折叠屏感知与适配
android
HelloBan5 小时前
setHintTextColor不生效
android
洞窝技术7 小时前
从0到30+:智能家居配网协议融合的实战与思考
android
QING6188 小时前
SupervisorJob子协程异常处理机制 —— 新手指南
android·kotlin·android jetpack
毕设源码-朱学姐8 小时前
【开题答辩全过程】以 基于安卓的停车位管理系统与设计为例,包含答辩的问题和答案
android