BatteryService 與電池統計
intro
在 Android 系統中,電池管理是一項關鍵任務,因為行動裝置的效能與續航力往往決定了使用者體驗。Android Framework 內建一套電池監控與統計系統,透過 BatteryService 來負責整體電池狀態管理,並由 BatteryStatsService 蒐集與彙整電池使用數據。這些數據最終會提供給系統服務、應用程式,甚至透過 adb 工具或分析平台呈現。
在早期,Google 提供了 Battery Historian 作為可視化電池消耗的分析工具,但如今已不再維護,取而代之的是 System Tracing、Macrobenchmark 電源指標以及 Android Studio 的電源分析器。因此,理解 BatteryService 的角色 與 現代化電池效能分析方法 對 Android 開發者來說非常重要。
BatteryService 的角色
BatteryService 屬於 Android Framework 層級的一個核心服務,啟動於 SystemServer 中,主要負責以下任務:
- 即時電池狀態管理
- 監控電池電量 (level)
- 監控是否正在充電 (charging status)
- 監控充電方式 (AC, USB, Wireless)
- 偵測電池健康狀態 (health, temperature)
- 廣播電池事件
- 當電池狀態發生變化時,BatteryService 會透過 Intent 廣播事件,例如:
- ACTION_BATTERY_CHANGED
- ACTION_POWER_CONNECTED
- ACTION_POWER_DISCONNECTED
- 與 PowerManagerService 協作
- BatteryService 與 PowerManagerService 搭配,根據電量與充電狀態決定省電策略,例如:
- 低電量模式 (Battery Saver)
- Doze 模式的觸發
- 數據收集
- 與 BatteryStatsService 搭配,將電量消耗分門別類歸屬於應用程式、UID、系統模組,最終提供 adb bugreport 或開發工具使用。
BatteryStats 與耗電歸因
BatteryService 本身僅負責電池狀態,但真正的數據統計由 BatteryStatsService 完成。BatteryStats 的核心在於耗電歸因 (Attribution):
- UID 層級耗電追蹤
- 每個 App 對應唯一 UID,BatteryStats 會統計 UID 在以下資源上的消耗:
- CPU 時間
- 無線網路活動 (Mobile/Wi-Fi)
- GPS 使用時間
- 螢幕使用時間
- Wakelock 保持時間
- 事件紀錄
- BatteryStats 不僅紀錄數據,還記錄「事件」,例如螢幕點亮、螢幕關閉、網路連線狀態切換。這些事件可以與電量曲線對照,讓開發者知道「某功能」是否異常耗電。
- 資料輸出
- BatteryStats 資料可以透過:
- adb shell dumpsys batterystats
- adb bugreport
- 系統 API (BatteryManager)
Battery Historian 的角色與退場
過去,Google 提供 Battery Historian 作為圖形化工具,用來解析 bugreport 中的電池數據,能夠顯示:
- 電量變化曲線
- 系統事件時間軸 (螢幕開關、網路狀態、wakelock)
- App 的耗電責任歸因
但 Battery Historian 已不再主動維護。原因主要有:
- 工具老舊,依賴 bugreport 的資料解析
- 開發者體驗不足,需額外安裝與配置
- Google 推出 新一代效能分析工具
現代化的電池效能分析工具
取代 Battery Historian 的,是以下幾種方式:
- 系統追蹤 (System Tracing)
- Android 原生工具,支援從 Developer Options 或 Perfetto 收集 Trace。
- 可觀察 CPU、GPU、I/O、電源狀態。
- 適合 Debug 耗電尖峰 與 效能瓶頸。
[App 層]
| (API Trace Events)
v
[BatteryStats + Power HAL] -- 收集耗電事件 -->
v
[System Tracing/Perfetto] -- 可視化 --> Chrome UI
- Macrobenchmark 電源指標
- Jetpack Macrobenchmark 提供 App 自動化效能測試,支援 Startup、Frame Rendering、電源消耗。
- 可以整合 CI/CD,持續追蹤版本間的耗電變化。
- 適合開發者比較不同版本的耗電行為。
Example:
@RunWith(AndroidJUnit4::class)
@LargeTest
class PowerBenchmark {
@get:Rule
val benchmarkRule = MacrobenchmarkRule()
@Test
fun batteryUsageTest() = benchmarkRule.measureRepeated(
packageName = "com.example.app",
metrics = listOf(PowerMetric()),
iterations = 5,
setupBlock = {
startActivityAndWait()
}
) {
device.waitForIdle()
}
}
- Android Studio 電源分析器 (Power Profiler)
- 在 Android Studio Profiler 中提供可視化耗電分析。
- 可即時顯示 CPU/GPU 活動 與 電池消耗曲線。
- 適合互動式調試。
+------------------------------------+
| Android Studio Profiler |
| |
| CPU Usage | GPU Usage | Power |
| -------------|-------------|-------|
| 45% | 60% | 150mA|
+------------------------------------+
BatteryService 與電源策略
BatteryService 與 Power HAL 以及 PowerManagerService 有密切合作:
- 低電量警告
- BatteryService 偵測到低於閾值 (例如 15%) 時,觸發低電量模式。
- Doze 模式
- 當裝置進入長時間待機,BatteryService 與 PowerManager 會限制網路、Alarm、JobScheduler。
- 充電優化
- 支援不同充電模式:快充、無線充電。
- 提供充電中熱度監控,避免電池損壞。
開發建議
- 避免長時間持有 Wakelock
- 使用 JobScheduler 或 WorkManager 取代。
- 正確使用前景服務
- 不要濫用 ForegroundService,會導致持續耗電。
- 監控版本耗電差異
- 將 Macrobenchmark PowerMetric 納入 CI。
- 利用系統工具 Debug
- Trace 系統事件 → 找出異常耗電。
- 使用 Studio Profiler 即時監控。
summary
- BatteryService 是電池管理的核心,負責狀態監控與廣播。
- BatteryStats 收集耗電數據,進行 UID 層級的歸因。
- Battery Historian 已過時,Google 建議改用:
- System Tracing (Perfetto)
- Macrobenchmark PowerMetric
- Android Studio Power Profiler