Android16 SystemService.onBootPhase 调用时机

SystemService.onBootPhase 调用时机

1. 方法说明

onBootPhase(int phase)SystemService 提供的系统服务启动生命周期回调方法。

源码位置:

frameworks/base/services/core/java/com/android/server/SystemService.java

方法定义如下:

复制代码
public void onBootPhase(@BootPhase int phase) {}

系统服务继承 SystemService 后,可以通过 @Override 重写该方法,在 Android 系统启动的不同阶段执行对应的初始化逻辑。

需要注意:这里的基类是 SystemService,不是 SystemServerSystemServer 负责启动和管理系统服务,具体服务通常继承 SystemService

2. SystemService 生命周期

系统服务的基本生命周期如下:

复制代码
创建 SystemService 对象
    -> 调用构造方法
    -> 调用 onStart()
    -> 多次调用 onBootPhase(phase)
    -> 到达 PHASE_BOOT_COMPLETED

其中:

  • 构造方法用于保存 Context 和初始化成员变量。
  • onStart() 用于启动服务,并通过 publishBinderService() 发布 Binder 服务。
  • onBootPhase(int phase) 会在系统启动的多个阶段被调用。
  • 所有生命周期方法都运行在 system_server 的主线程中。

3. 启动阶段

当前 Android 16 源码中主要启动阶段如下:

阶段常量 数值 主要含义
PHASE_WAIT_FOR_DEFAULT_DISPLAY 100 默认显示设备可用
PHASE_WAIT_FOR_SENSOR_SERVICE 200 等待 SensorService 可用
PHASE_LOCK_SETTINGS_READY 480 锁屏设置数据可用
PHASE_SYSTEM_SERVICES_READY 500 核心系统服务可安全访问,例如 PowerManager、PackageManager
PHASE_DEVICE_SPECIFIC_SERVICES_READY 520 设备相关系统服务可用
PHASE_ACTIVITY_MANAGER_READY 550 系统服务可以发送广播
PHASE_THIRD_PARTY_APPS_CAN_START 600 第三方应用可以启动或绑定
PHASE_BOOT_COMPLETED 1000 系统启动完成,允许用户交互

服务不一定会收到所有阶段。SystemService 的注释说明,服务启动阶段之前的阶段不会发送给该服务;服务从自身注册或启动阶段开始接收后续阶段回调。

4. 方法调用链

4.1 SystemServer 触发启动阶段

SystemServer 在系统启动流程中依次调用:

复制代码
mSystemServiceManager.startBootPhase(
        t, SystemService.PHASE_SYSTEM_SERVICES_READY);

以及其他阶段对应的 startBootPhase()

4.2 SystemServiceManager 分发回调

SystemServiceManager.startBootPhase() 会遍历所有已经启动的系统服务,并调用每个服务的 onBootPhase()

复制代码
for (int i = 0; i < serviceLen; i++) {
    final SystemService service = mServices.get(i);
    service.onBootPhase(mCurrentPhase);
}

因此,系统服务本身通常不需要主动调用 onBootPhase()。只要它已经被 SystemServiceManager 注册并启动,系统会在对应启动阶段自动调用该方法。

5. PHASE_BOOT_COMPLETED 的调用时机

PHASE_BOOT_COMPLETED 的数值为 1000,是最后一个启动阶段。

在当前代码中,ActivityManagerService.finishBooting() 完成系统启动收尾工作后调用:

复制代码
mSystemServiceManager.startBootPhase(
        t, SystemService.PHASE_BOOT_COMPLETED);

调用位置:

SSI/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

该阶段表示:

  • 核心系统服务已经启动。
  • 系统启动流程已经进入完成阶段。
  • Home 应用已经启动或系统已准备进入用户交互状态。
  • 系统服务可以执行依赖完整系统环境的初始化工作。

它是 SystemServer 内部的生命周期阶段,不等同于应用层接收的 Intent.ACTION_BOOT_COMPLETED 广播,但两者都发生在系统启动完成附近。

6. 示例:Zigbee 监控服务

自定义系统服务可以这样处理启动完成阶段:

复制代码
@Override
public void onBootPhase(int phase) {
    Slog.i(TAG, "XXService onBootPhase: " + phase);
    if (phase == PHASE_BOOT_COMPLETED) {
        Slog.i(TAG, "PHASE_BOOT_COMPLETED reached");
        startXXXXXX();
    }
}

执行过程如下:

  1. 系统启动过程中,系统服务可能多次进入 onBootPhase()
  2. 每次调用都会传入当前阶段值。
  3. 前面的阶段只记录日志,不启动 Zigbee 监控。
  4. phase 等于 PHASE_BOOT_COMPLETED,调用 startZigbeeMonitoring()

因此,startZigbeeMonitoring() 会在系统服务收到启动完成阶段回调时执行,而不是在设备上电的最早时刻执行。

7. 使用建议

7.1 适合放在 onBootPhase 的工作

  • 等待其他系统服务可用后再进行初始化。
  • 注册依赖系统服务的监听器。
  • 启动依赖系统环境的硬件监控任务。
  • 在第三方应用可以启动前完成系统服务准备。

7.2 选择阶段的原则

  • 只依赖核心系统服务时,可考虑 PHASE_SYSTEM_SERVICES_READY
  • 需要发送广播时,应至少等到 PHASE_ACTIVITY_MANAGER_READY
  • 需要启动或绑定第三方应用时,应等到 PHASE_THIRD_PARTY_APPS_CAN_START
  • 需要等系统完全进入用户交互状态时,可使用 PHASE_BOOT_COMPLETED

7.3 注意事项

  • onBootPhase()system_server 主线程中执行,不应执行长时间阻塞操作。
  • startZigbeeMonitoring() 如果包含设备访问、串口打开或持续监听,应尽量切换到独立线程或 HandlerThread 执行。
  • 服务必须先通过 SystemServiceManager 启动和注册,否则不会收到后续 boot phase 回调。
  • 如果服务使用 @Service 注解声明了启动阶段,早于该启动阶段的回调不会发送给服务。

8. 相关源码

  1. /frameworks/base/services/core/java/com/android/server/SystemService.java
  2. /frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
  3. /frameworks/base/services/java/com/android/server/SystemServer.java
  4. /frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
相关推荐
swithun1 小时前
不用 WebView,我用 Kotlin + Compose Multiplatform 重写 Mermaid,并做了 2048 组对拍
android·开源·kotlin
深入云栈1 小时前
Netty 4.2.x 源码深度解析 (十三):Epoll 传输 —— Linux 高性能 IO 的 Netty 实现
java·后端
初願致夕霞1 小时前
Linux 进程间通信(IPC)机制详解:管道、FIFO 与 System V 共享内存
linux·服务器·c++
ynchyong1 小时前
Linux nohup 后台服务合并标准错误输出到一个文件
java·linux·运维
用户3126874877201 小时前
Lombok 的 @Data 到底怎么工作的?Java 注解处理器实战全链路拆解
java
xx~t1 小时前
嵌入式——51单片机3
linux·c语言·嵌入式硬件·51单片机
傲世仙尊1 小时前
从磁盘硬件到Ext文件系统-Linux磁盘级文件系统学习笔记
linux·运维·服务器·开发语言·c++
AI吃大瓜2 小时前
人脸检测和行人检测4:Android实现YOLOv8 YOLO11 YOLO26人脸检测和人体检测(含源码,可实时检测)
android·yolo·人脸检测·人体检测·行人检测·yolo26
星源~2 小时前
Linux - Trae Code Linux 环境嵌入式开发指南
linux·mcu·嵌入式·trae code