4. 系统休眠机制概述

在 Android 电源管理体系中,系统休眠(System Suspend)是功耗控制的核心手段之一。当设备长时间无用户交互、无前台任务、无关键后台工作时,内核会尝试让整机进入低功耗状态,以延长待机时间。理解系统休眠,不能只停留在“屏幕熄灭”这一表层现象,而要从定义、状态分类、Suspend/Resume 流程以及对系统行为的影响四个层面建立完整认知。

一、系统休眠的定义

系统休眠是指:在满足特定条件后,Android 通过内核电源管理框架,将 CPU、外设、总线、时钟等逐步置于低功耗状态,仅保留必要的唤醒源,使整机进入一种“可被事件唤醒的低功耗静止态”。它不同于关机,也不同于应用被杀死,系统上下文、内存内容、进程状态仍然保留,只是执行被冻结、硬件被降耗。

从软件栈看,休眠由多层协作完成:应用与框架层通过 WakeLock、Alarm、JobScheduler 等表达“是否允许休眠”;系统服务层(PowerManagerService)汇总约束并决定休眠时机;内核层(PM Core、Runtime PM、SoC 电源域)执行真正的设备挂起。因此,系统休眠不是单一模块的行为,而是一条跨层协作链。

休眠的本质不是“停止一切”,而是“冻结非必要活动,保留唤醒能力”。判断休眠是否健康,关键看两点:能否顺利进入低功耗态,以及能否被预期事件及时唤醒。

二、休眠状态分类

Android 与 Linux 内核中,休眠并非只有一种状态。常见分类包括:

  • Runtime PM(运行时电源管理):单个设备在空闲时独立进入低功耗,不影响整机运行,例如屏幕关闭后摄像头模组单独挂起。
  • System Suspend(系统挂起):整机进入低功耗,CPU 停止调度,外设按序挂起,是最典型的“休眠”。
  • Suspend-to-RAM(STR):内存保持自刷新,上下文保留,唤醒速度快,是移动设备最常用的休眠形态。
  • Suspend-to-Disk(STD/Hibernate):将内存内容写入存储后断电,功耗最低但恢复慢,Android 手机较少使用。
  • Doze / Deep Doze:Android 框架层的省电模式,通过延迟网络、对齐任务、限制唤醒,间接促成更长时间的系统休眠。

这些状态并非互斥,而是层层递进:Runtime PM 是设备级,System Suspend 是整机级,Doze 是策略级。工程中常说的“进休眠”,通常指 System Suspend 成功执行。

三、Suspend 与 Resume 流程

系统休眠的核心流程可概括为“冻结进程 → 挂起设备 → 关闭非必要电源 → 等待唤醒 → 恢复设备 → 解冻进程”。下图展示了这一信号与状态流转关系:

System Suspend / Resume 状态流转 冻结用户进程 freeze processes 挂起设备驱动 device suspend 关闭非必要电源 power domain off CPU 停止调度 suspend state 唤醒源触发 RTC / 中断 / 按键 / 网络 / 传感器 恢复设备驱动 device resume 恢复电源与时钟 power / clock on 解冻用户进程 thaw processes 系统恢复运行 system running Suspend 路径 Resume 路径

在 Suspend 阶段,内核会先调用 pm_suspend(),依次执行 dpm_suspend() 挂起设备、suspend_enter() 冻结进程并关闭中断,最终由 SoC 进入低功耗态。Resume 阶段则反向执行:唤醒源触发中断,SoC 退出低功耗,dpm_resume() 恢复设备,最后解冻进程。整个过程要求“挂起顺序”与“恢复顺序”严格对称,否则容易出现设备状态不一致。

# 查看当前系统休眠状态与唤醒源统计
adb shell cat /sys/power/state
adb shell cat /sys/power/wake_lock
adb shell dumpsys power | grep -i "mWakefulness\|mHoldingWakeLockSuspendBlocker"

# 典型日志片段
PM: Syncing filesystems ... done.
Freezing user space processes ... (elapsed 0.002 seconds) done.
PM: suspend entry (deep)
PM: suspend exit

四、休眠对系统行为的影响

系统休眠会显著改变应用与系统的运行节奏,工程中必须重点关注以下影响:

影响维度 休眠前 休眠中 恢复后
CPU 调度 正常调度 停止,仅保留唤醒中断 重新调度,任务积压可能突增
网络连接 保持活跃 Wi-Fi/蜂窝可能断开或降耗 需重连,可能产生延迟
定时任务 按计划执行 Alarm 被延迟或合并 集中触发,需防抖
传感器 持续采样 部分关闭或降频 重新初始化
应用进程 可运行 被冻结,不消耗 CPU 解冻,需处理状态恢复

这些影响意味着:应用不能假设自己始终在运行。例如,一个依赖 Handler.postDelayed() 的定时逻辑,在系统休眠期间不会按时执行;一个长连接在休眠中可能被断开;一个正在写入文件的任务可能被冻结在中间状态。正确的做法是使用 AlarmManager、WorkManager、JobScheduler 等系统认可的调度机制,并在 onResume() 或广播回调中重新校验状态。

常见误区:把“屏幕熄灭”等同于“系统已休眠”。实际上,屏幕关闭后若仍有 WakeLock 被持有、有音频播放、有导航定位,系统可能长时间无法进入 Suspend。排查休眠问题,第一步应检查 /sys/power/wake_lock 与 dumpsys power 中的 WakeLock 持有情况。

五、案例与复盘

某音乐应用在后台播放时,设备待机功耗偏高。排查发现,应用持有一个 PARTIAL_WAKE_LOCK 且未在暂停播放时释放,导致系统无法进入 Suspend。修复方式是在 onPause() 或播放停止回调中及时释放 WakeLock,并改用 MediaSession 与前台服务管理播放状态。修复后,待机电流从 18mA 降至 3mA 左右。

另一个典型案例是闹钟延迟:应用使用 Handler 实现倒计时,休眠后倒计时停滞,闹钟不响。改为 AlarmManager.setExactAndAllowWhileIdle() 后,系统可在 Doze 下仍按需唤醒,问题解决。

理解系统休眠,建议建立“三层视角”:框架层看 WakeLock 与 Doze 策略,内核层看 Suspend/Resume 流程,硬件层看电源域与唤醒源。三层对齐,才能既省电又不丢功能。

综上,系统休眠是 Android 电源管理的基石机制。它通过冻结进程、挂起设备、关闭电源来降低待机功耗,同时保留唤醒能力。掌握休眠状态分类、Suspend/Resume 对称流程以及休眠对调度、网络、定时任务的影响,是后续进行功耗优化与问题排查的前提。