You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免BatteryManager抛出DeadSystemException异常?

修复DeadSystemException异常的方案

问题原因

DeadSystemException是Android系统抛出的特殊异常,表明核心系统服务已终止,此时应用无法再正常与系统服务(比如电池管理服务)交互。你的代码虽然捕获了该异常,但仅返回默认值后继续循环,这不仅会导致后续重复抛出异常,还可能因系统服务失效无法获取有效数据,最终触发应用崩溃。

修复步骤

  1. 捕获异常后终止协程:一旦捕获到DeadSystemException,立即终止循环和协程,避免无效的重复尝试。
  2. 添加用户提示:在主线程告知用户系统服务异常,建议重启应用。
  3. 扩大异常捕获范围:捕获所有RuntimeException,避免其他未预期的系统服务异常导致崩溃。
  4. 协程存活判断:使用isActive判断协程状态,配合lifecycleScope的生命周期自动取消特性,避免内存泄漏。

修复后的代码

lifecycleScope.launch(Dispatchers.IO) {
    try {
        while (isActive) {
            currentNow = try {
                batteryManager?.getIntProperty(BatteryManager.BATTERY_PROPERTY_CURRENT_NOW) ?: 1
            } catch (e: DeadSystemException) {
                // 系统服务已死亡,终止循环并提示用户
                withContext(Dispatchers.Main) {
                    Toast.makeText(requireContext(), "系统服务异常,请重启应用", Toast.LENGTH_LONG).show()
                }
                break
            } catch (e: RuntimeException) {
                // 捕获其他系统服务相关异常
                Log.e("BatteryMonitor", "获取电池电流失败", e)
                1
            }

            val curValue = limitDigits(currentNow)
            val cur = "$curValue mA"
            val cur1 = "$batteryCur : $cur"
            val power = (curValue.toInt() * batteryVoltage) / 1000000.0
            val powerDis = "%.2f".format(power) + " W"
            val powerDisTop = "$batteryPow : $powerDis"
            
            withContext(Dispatchers.Main) {
                txtBatteryCurrentDis.text = cur
                txtBatteryCurrentTop.text = cur1
                txtBatteryPowerDis.text = powerDis
                txtBatteryPowerTop.text = powerDisTop
            }
            delay(1000)
        }
    } catch (e: CancellationException) {
        Log.d("BatteryMonitor", "电池监控协程已终止")
    }
}

private fun limitDigits(n: Int): String {
    val abs = abs(n)
    var absoluteValueFinal = abs
    return try {
        absoluteValueFinal = if (isCharging) absoluteValueFinal else absoluteValueFinal * -1
        if (abs.toString().length >= 6) {
            absoluteValueFinal /= 1000
            if (abs(absoluteValueFinal).toString().length >= 6) {
                absoluteValueFinal /= 1000
            }
        }
        if (n != 0 && n != Int.MIN_VALUE && n != Int.MAX_VALUE) {
            if (isBatteryFull) "0" else absoluteValueFinal.toString()
        } else {
            "0"
        }
    } catch (ex: Exception) {
        ex.printStackTrace()
        "0"
    }
}

额外优化说明

  • 简化了limitDigits函数的嵌套逻辑,提升代码可读性。
  • 添加日志记录,方便排查其他异常场景。
  • 利用lifecycleScope的特性,协程会随页面生命周期自动取消,避免内存泄漏。

内容的提问来源于stack exchange,提问作者Yasiru Nayanajith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 03:12:07