15、网络与电量:WiFi扫描优化、移动数据优化、蓝牙低功耗(BLE)、NFC功耗
各位同学,咱们今天聊一个很实在的话题——网络模块怎么省电。你想想看,手机里最耗电的几大件,屏幕排第一,CPU排第二,第三名大概率就是无线通信这一堆了。WiFi、4G/5G、蓝牙、NFC,哪个不是电老虎?我这些年做功耗优化,光是跟这几个模块打交道就占了差不多一半的时间。今天我把压箱底的经验拆开揉碎了讲给你听。
核心观点:网络模块的功耗优化,本质上是「连接频率」和「数据量」的博弈。你控制得越精细,电池就越耐用。
15.1 WiFi扫描优化——别让手机像个无头苍蝇
WiFi扫描是很多App的「隐形杀手」。你打开一个地图App,它要扫WiFi;你刷个短视频,它也要扫WiFi。每次扫描,WiFi芯片都要从休眠状态唤醒,发射探测帧,等待AP回应。这个过程大概持续2~3秒,电流能飙到200mA以上。
我在项目中遇到过最夸张的情况:某个天气App每30秒扫一次WiFi,一天下来光扫描就耗掉了15%的电。用户反馈手机发热,一查日志,好家伙,WiFi扫描占了唤醒锁的80%。
优化策略
- 降低扫描频率:不要用固定间隔扫描。我建议用「指数退避」策略——第一次扫描后等30秒,第二次等1分钟,第三次等2分钟,以此类推。如果检测到WiFi环境变化(比如信号强度突变),再重置回短间隔。
- 使用Passive扫描:主动扫描(Active Scan)会发送Probe Request,被动扫描(Passive Scan)只是监听Beacon帧。后者功耗低很多,但发现新网络的速度会慢一些。在后台场景下,优先用被动扫描。
- 合并扫描请求:如果有多个App同时需要WiFi扫描,系统应该合并成一个扫描请求。Android从6.0开始就支持这个机制,但很多App没有正确实现。
我的小技巧:在AndroidManifest里声明 android:scanMode="SCAN_MODE_LOW_POWER",系统会自动帮你做扫描节流。不过要注意,这个模式在Android 12以上才稳定。
15.2 移动数据优化——蜂窝网络下的生存法则
移动数据(4G/5G)的功耗比WiFi高一个数量级。为什么?因为基站距离远,手机需要更大的发射功率。而且蜂窝网络有RRC状态机——IDLE、Connected、DRX。每次状态切换都要消耗额外能量。
说白了,最耗电的不是传输数据本身,而是「建立连接」和「保持连接」的过程。你发一个10KB的请求,可能90%的能量都花在了建立RRC连接上。
优化要点
- 批量传输:把多个小数据包攒起来,一次性发送。比如日志上报,不要每条日志单独发,攒够10条或者每隔5分钟发一次。我见过一个App每2秒发一次心跳包,一天下来光心跳就耗了8%的电。
- 使用JobScheduler:Android的JobScheduler可以帮你选择最佳时机执行网络任务。比如在WiFi环境下、充电时、或者系统空闲时。不要自己写定时器。
- 避免长连接:除非你的App需要实时推送,否则尽量用短连接。长连接意味着手机要一直保持RRC Connected状态,电流在50~100mA之间。而短连接完成后,手机可以迅速回到IDLE状态,电流只有几毫安。
注意:5G网络下,RRC状态机更复杂,有多个子状态。在信号不好的地方,手机可能会频繁在4G和5G之间切换,功耗会急剧上升。我建议在信号强度低于-110dBm时,主动降级到4G。
15.3 蓝牙低功耗(BLE)——省电的典范
BLE是蓝牙4.0之后推出的低功耗版本。它的设计哲学就是「能睡就睡」。传统蓝牙(BR/EDR)连接后要一直保持活动状态,而BLE通过广播、扫描、连接三个阶段的精细控制,把功耗降到了传统蓝牙的十分之一甚至更低。
我记得有一次做智能手环的配对优化。手环每100ms广播一次,手机端每200ms扫描一次。两者配合不好,经常要等好几个广播周期才能完成配对。后来我把扫描窗口调整到与广播周期对齐,配对时间从8秒降到了1.5秒,功耗也降了40%。
BLE优化关键点
| 参数 | 默认值 | 优化建议 | 说明 |
|---|---|---|---|
| 广播间隔 | 100ms | 200ms~1s | 广播越频繁,发现越快,但功耗越高。后台场景建议用1s以上。 |
| 扫描窗口 | 30ms | 10ms~20ms | 扫描窗口越小,功耗越低,但可能漏掉广播包。需要根据场景平衡。 |
| 连接间隔 | 7.5ms | 30ms~100ms | 连接间隔越大,双方休眠时间越长,功耗越低。非实时场景建议用50ms以上。 |
| MTU大小 | 23字节 | 512字节 | 增大MTU可以减少数据包数量,降低传输功耗。但需要双方协商支持。 |
避坑指南:我曾经遇到一个BLE设备,连接后每隔3秒发一个空包保持连接。这个空包本身不耗多少电,但每次都会唤醒手机端的蓝牙芯片,导致手机无法进入深度睡眠。后来我建议设备端把空包间隔延长到30秒,手机端功耗直接降了60%。
15.4 NFC功耗——近场通信的能耗真相
NFC的功耗其实很低,因为它只在非常近的距离(通常4cm以内)工作,而且通信时间极短。一次典型的NFC交易(比如刷公交卡),从检测到完成只需要不到100ms,功耗大概在50mJ左右。相比WiFi或蜂窝网络,这几乎可以忽略不计。
但NFC有一个隐藏的耗电点——轮询。手机在开启NFC功能后,会每隔一段时间发射射频场来检测附近是否有NFC标签。这个轮询过程虽然每次只持续几毫秒,但如果一直开着,一天下来也会消耗几十毫安时的电量。
优化建议
- 按需开启:不要默认开启NFC。很多用户其实很少用NFC,但手机厂商为了「方便」,默认就是开启的。我建议在设置里增加一个「智能NFC」选项——当检测到手机靠近某个NFC设备时自动开启,离开后自动关闭。
- 降低轮询频率:如果必须常开NFC,可以把轮询间隔从默认的200ms延长到500ms甚至1秒。代价是响应速度会变慢,但省电效果明显。
- 使用HCE(Host-based Card Emulation)时注意:HCE模式下,手机需要一直监听NFC事件,这会阻止CPU进入深度睡眠。我建议在不需要HCE服务时,主动关闭NFC的监听功能。
一个冷知识:NFC的射频场强度是可以调节的。有些手机支持「低功耗模式」,把射频场强度降低30%,通信距离会缩短到2cm以内,但功耗能降一半。适合用在门禁卡这种对距离不敏感的场景。
知识体系总览
下面这张图把今天讲的内容串起来了。你可以看到,四个网络模块的优化思路其实是一致的:减少唤醒次数、缩短活动时间、合并数据传输。
好了,这一章的内容就到这里。网络功耗优化是个细活,每个模块都有它的脾气。你只要记住一个原则:让无线模块多睡觉,少干活。具体怎么睡、睡多久,就是今天讲的这些参数和策略。下次你在项目里遇到手机耗电快的问题,不妨先从WiFi扫描和移动数据入手,往往能立竿见影。
公众号:蓝海资料掘金营,微信deep3321