2. Android电源管理基础
Android 的电源管理并不是从零构建的独立体系,而是建立在 Linux 内核电源管理子系统之上,再结合移动设备的交互特征、应用模型与硬件约束逐层封装出来的。理解这条“从内核到框架”的演进脉络,是后续分析休眠异常、待机功耗与唤醒锁问题的前提。本节从发展历程、内核子系统、Android 架构与关键术语四个角度建立整体认知。
一、电源管理发展历程:从省电到系统级协同
早期嵌入式 Linux 的电源管理主要解决“空闲时降频、关机时断电”,手段集中在 CPU 调频与整机挂起。随着智能手机普及,设备需要在“屏幕熄灭但仍在收消息、放音乐、导航”等场景下保持部分功能,传统整机休眠模型不再适用。Android 由此引入两个关键变化:一是把“是否允许休眠”的决策权部分交给应用与系统服务,二是把电源状态与用户可见的交互状态绑定。
演进大致可分为三个阶段:
- 内核基础阶段:以 CPUIdle、CPUfreq、Runtime PM、System Suspend 为核心,解决“谁在运行、谁在耗电、何时挂起”。
- Android 框架阶段:引入 WakeLock、AlarmManager、JobScheduler、Doze/App Standby,把省电策略从内核上移到应用行为治理。
- 系统级协同阶段:以 Power HAL、Suspend 统计、电源域与热管理联动为代表,强调跨模块的功耗归因与可观测性。
二、Linux 内核电源管理子系统:状态与机制
内核侧提供的是可被上层调用的电源能力,主要包括以下几类:
| 子系统 | 作用对象 | 典型机制 | 关注点 |
|---|---|---|---|
| CPUFreq | CPU 频率/电压 | 调频策略、governor | 性能与功耗平衡 |
| CPUIdle | CPU 空闲状态 | C-State 进入/退出 | 空闲深度与唤醒延迟 |
| Runtime PM | 单个设备 | 设备运行时挂起 | 设备级动态省电 |
| System Suspend | 整机 | 冻结进程、挂起设备 | 进入/退出休眠 |
| Regulator | 供电域 | 电压/电流调节 | 电源域开关与约束 |
其中 System Suspend 是 Android 休眠分析的核心。其典型流程是:用户空间写入 /sys/power/state,内核冻结用户进程与内核线程,依次挂起各设备,最后让 CPU 进入低功耗状态;任一设备或唤醒源未就绪,都会导致休眠失败或频繁唤醒。
# 查看当前支持的休眠状态
cat /sys/power/state
# 典型输出:freeze mem disk
# 查看休眠统计(部分平台)
cat /sys/power/suspend_stats/success
cat /sys/power/suspend_stats/fail
cat /sys/power/suspend_stats/last_failed_dev
需要特别区分两个概念:Suspend 是整机进入低功耗状态,Runtime PM 是设备在系统运行期间独立挂起。前者影响全局,后者影响局部,二者通过设备树与电源域相互约束。
三、Android 电源管理架构:分层与关键组件
Android 在 Linux 之上增加了框架层与硬件抽象层,形成如下结构:应用通过 PowerManager 申请 WakeLock 或设置 Alarm;系统服务(PowerManagerService、AlarmManagerService、JobScheduler)汇总请求并决策;Power HAL 与内核交互,最终由内核执行频率、空闲与休眠动作。
从图中可以看出,应用层的每一次 WakeLock 申请都会向上汇总到 PowerManagerService,再由 Power HAL 与内核交互。若应用持有 WakeLock 不放,内核就无法进入 Suspend,整机功耗会显著上升。
四、关键术语与常见误区
掌握以下术语,能避免在排查时把不同层级的问题混为一谈:
- WakeLock:应用持有的“阻止休眠”锁,分为 PARTIAL、FULL、SCREEN_DIM 等类型。
- Suspend:整机进入低功耗状态,所有非唤醒源设备被挂起。
- Resume:从 Suspend 恢复,通常由中断或 RTC 触发。
- Wakeup Source:能够把系统从休眠中唤醒的中断源,如电源键、RTC、Modem。
- Doze:屏幕关闭且未充电时,系统延迟网络与任务,降低唤醒频率。
- App Standby:对长期未使用的应用限制后台网络与任务。
dumpsys power 与内核 suspend 统计共同判断。一个典型的排查场景是:设备夜间待机耗电偏高。此时应先确认是否进入 Suspend,再检查是否有应用长期持有 PARTIAL WakeLock,最后核对 Alarm 与 JobScheduler 的唤醒频率。只有把“框架层请求”和“内核层状态”对齐,才能定位真正的耗电源。
# 查看 WakeLock 持有情况
adb shell dumpsys power | grep -i "wake lock"
# 查看 Alarm 与 Job 统计
adb shell dumpsys alarm | head -50
adb shell dumpsys jobscheduler | head -50
# 查看内核休眠失败原因
adb shell cat /sys/power/suspend_stats/last_failed_dev
综上,Android 电源管理的基础可以概括为:内核提供状态与机制,框架提供策略与约束,应用提供请求与行为。三者之间的边界与交互,正是后续分析休眠异常、功耗归因与省电优化的主线。