iT邦幫忙

2025 iThome 鐵人賽

DAY 19
0

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 的,是以下幾種方式:

  1. 系統追蹤 (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
  1. 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()
    }
}
  1. 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

上一篇
#17
下一篇
#19
系列文
安豬複習20
  1. 16
    #15
  2. 17
    #16
  3. 18
    #17
  4. 19
    #18
  5. 20
    #19
完整目錄
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言