电池消耗优化与长时间使用策略
为什么 AR 应用特别耗电
ARCore 应用的功耗结构和普通应用完全不同——它是唯一一个持续让手机摄像头 + CPU + GPU + IMU + 屏幕全负荷运转的应用类型:
| 组件 | 典型功耗 | 说明 |
|---|---|---|
| 屏幕 | 3~8W | 持续最高亮度(AR 应用通常需要看清楚画面) |
| CPU | 3~6W | SLAM + 平面检测 + 光照估算 + 你的逻辑 + 后台线程 |
| GPU | 2~5W | 3D 渲染 + 遮挡渲染 + Depth API 处理 |
| 摄像头 | 2~3W | 持续开启(很多手机不支持后台录制) |
| IMU | ~0.5W | 持续高频率采样(100~500Hz) |
| GPS | ~0.5W | 如果用 Geospatial API |
| 网络 | ~1W(峰值) | Cloud Anchors / Geospatial API 的数据传输 |
加起来轻松超过 15W——接近手机快充的功率。普通网页浏览功耗只有 2~3W。
热量问题
15W 功耗如果持续运行,手机很快会发热到 45°C 以上。Android 和 iOS 都有温度保护机制:
- 超过 42°C:屏幕自动降低亮度,CPU/GPU 降频
- 超过 45°C:CPU/GPU 强制降频到 50%~70%
- 超过 48°C:自动关闭后台进程,可能杀掉你的应用
- iPhone 有专门的 Thermal State(Normal → Slightly Warm → Warm → Hot → Critical)
热量不仅让体验变差(掉帧),还会触发用户投诉。降低功耗同时就能降低发热。
降低功耗的策略(按收益排序)
策略一:降低渲染分辨率(同时省 GPU + CPU + 屏幕)
把渲染分辨率降到物理分辨率的 60~75%,是 AR 应用最有效的功耗优化:
| 分辨率 | GPU 功耗降低 | 视觉影响 |
|---|---|---|
| 100% | 基准 | 无 |
| 75% | ~44% | 轻微(AR 摄像头画面已经占满屏幕,用户注意力在真实物体上) |
| 60% | ~64% | 有轻微模糊感 |
GPU 是最大的耗电组件之一,降低分辨率直接砍一半功耗。
策略二:帧率自适应(动态帧率)
不是所有时刻都需要 60fps:
// 设备温度较低时 60fps,温度上升后逐步降低
fun getTargetFrameRate(deviceTemperatureCelsius: Float): Int {
return when {
deviceTemperatureCelsius < 40f -> 60
deviceTemperatureCelsius < 43f -> 45
deviceTemperatureCelsius < 45f -> 30
else -> 24 // 极限温度,保证基本功能
}
}
iOS 上可以用 CADisplayLink.preferredFramesPerSecond;Android 上需要手动控制渲染循环频率。
策略三:摄像头分辨率选择
ARCore 默认用较高的摄像头分辨率(1080p)——大多数场景 720p 完全够用:
session.configure(
Session.Config(context).apply {
// 降低摄像头分辨率(某些版本通过 Android 配置)
// 或使用 Camera2 API 手动控制
}
)
降低摄像头分辨率能显著减少:
- SLAM 特征点提取的 CPU 开销
- SurfaceTexture → 渲染纹理的拷贝开销
- 摄像头传感器的功耗
策略四:减少不必要的 API 调用
| 关闭的 API | 节省的功耗 | 何时可以关 |
|---|---|---|
| HDR 光照估算 | ~10% | 光照效果要求不高时 |
| 平面检测 | ~5% | 不需要 Hit Test 时 |
| Depth API | ~15~25% | 不做遮挡时 |
| Cloud Anchors 后台同步 | ~5% | 暂时不需要托管/解析时 |
| 高频 Location 请求 | ~3% | 室内或 Geospatial 暂不需时 |
策略五:屏幕亮度管理
AR 应用通常让用户看到的效果越好——但强制降低屏幕亮度 20~30%,对功耗影响巨大:
// Android
val layoutParams = window.attributes
layoutParams.screenBrightness = 0.7f // 0~1,默认 1.0
window.attributes = layoutParams
// iOS
UIScreen.main.brightness = 0.7f
用户可能不会注意到亮度降低了——因为他们在用 AR 看真实世界。
Unity 中的功耗优化
// 1. 降低渲染分辨率
URPAsset.renderScale = 0.75f;
// 2. Quality Settings 关闭不必要的效果
QualitySettings.shadows = ShadowQuality.Disable; // 关闭阴影
QualitySettings.realtimeReflectionProbes = false; // 关闭实时反射
QualitySettings.billboardsFaceCameraPosition = false; // 关闭 Billboard 对齐相机
// 3. VSync + 帧率限制
Application.targetFrameRate = 30; // 或根据温度动态设置
// 4. Mobile Rendering Path
EditorSettings.mobileRenderingPath = MobileRenderingPath.Forward;
长时间使用的保护机制
计时 + 降温提示
private var arSessionStartTime = System.currentTimeMillis()
private var lastCoolingWarningTime = 0L
fun checkBatteryAndTemperature() {
// 检查使用时长
val elapsedMinutes = (System.currentTimeMillis() - arSessionStartTime) / 60000
if (elapsedMinutes > 10) {
// 建议用户休息一下
showUsageTip("长时间使用会消耗较多电量,建议休息一下或插上充电器")
}
// 检查温度
val batteryManager = getSystemService(Context.BATTERY_SERVICE) as BatteryManager
val temperature = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_TEMPERATURE)
val tempCelsius = temperature / 10f // Android 返回的是 1/10 摄氏度
if (tempCelsius > 45f && System.currentTimeMillis() - lastCoolingWarningTime > 5000) {
showCoolingTip("设备温度较高,建议移到阴凉处或关闭应用一段时间")
lastCoolingWarningTime = System.currentTimeMillis()
}
}
后台挂起
用户把应用切到后台时,必须完全暂停所有 ARCore 活动:
override fun onStop() {
super.onStop()
arSession?.pause()
// 不要调用 arSession?.destroy(),恢复时 pause/resume 即可
// destroy 后重新创建 Session 的开销很大
}
实际功耗数据参考
以下是某款中高端 Android 测试设备上的实际测量:
| 场景 | 平均功耗 | 10 分钟消耗 | 可用时间(3000mAh) |
|---|---|---|---|
| 普通浏览 | 2.5W | 0.42Wh | ~12 小时 |
| AR 应用(未优化) | 14.8W | 2.47Wh | ~1.5 小时 |
| AR 应用(75% 分辨率 + 30fps) | 8.2W | 1.37Wh | ~2.7 小时 |
| AR 应用(全优化) | 5.6W | 0.93Wh | ~4 小时 |
优化后的 AR 应用功耗降低了 62%,使用时间延长了 1.7 倍。