29、WiFi优化:WiFi扫描频率、网络切换策略、热点检测、WiFi RTT定位

WiFi优化这个话题,说实话,在Android系统性能优化里属于「看似简单,实则坑多」的那一类。很多开发者觉得WiFi嘛,能连上就行。但真正做过系统级优化的工程师都知道,WiFi模块要是没调好,用户的续航、网络体验、甚至定位精度都会出问题。

我个人习惯把WiFi优化拆成四个维度来看:扫描频率、网络切换、热点检测、以及RTT定位。咱们一个一个聊。

WiFi扫描频率:别让手机像个无头苍蝇

WiFi扫描是耗电大户,这一点做过功耗优化的朋友应该深有体会。我曾在某个项目里遇到过,用户反馈手机待机一晚上掉电20%,查来查去,罪魁祸首就是WiFi扫描频率太高——每10秒扫一次,CPU根本没法深度休眠。

Android系统默认的WiFi扫描策略其实已经做了权衡:

  • 屏幕亮着且连接WiFi:扫描间隔约60秒
  • 屏幕亮着但未连接WiFi:扫描间隔约30秒
  • 屏幕熄灭:扫描间隔拉长到120秒以上,甚至停止扫描

但问题是,很多第三方应用会通过WifiManager.startScan()主动发起扫描。你想想看,如果装了十几个应用,每个都来扫一下,那功耗能不高吗?

优化建议:

  • 在系统层限制第三方应用的扫描频率,比如每分钟最多允许发起一次扫描
  • 使用WifiManager.SCAN_ONLY_WITH_WIFI_OFF模式,避免在WiFi关闭时仍被唤醒扫描
  • 利用WifiManager.WIFI_STATE_CHANGED_ACTION广播,动态调整扫描策略
// 限制扫描频率的示例代码
public class ScanThrottleHelper {
    private static final long MIN_SCAN_INTERVAL_MS = 30_000; // 30秒
    private long lastScanTime = 0;

    public boolean canStartScan() {
        long now = SystemClock.elapsedRealtime();
        if (now - lastScanTime < MIN_SCAN_INTERVAL_MS) {
            return false; // 太频繁了,拒绝
        }
        lastScanTime = now;
        return true;
    }
}

网络切换策略:别让用户感觉「断网了」

网络切换,说白了就是手机在WiFi和移动数据之间做选择。我见过最糟糕的情况是:用户从家里走到电梯口,WiFi信号已经弱到不行了,但手机还死死抓着不放,结果网页死活打不开。

Android系统里有个关键参数叫WifiManager.THRESHOLD_QUALITY,它决定了什么时候触发网络切换。默认值一般是-70dBm到-80dBm之间。但说实话,这个阈值不能一刀切。

信号强度 等级 建议行为
-50dBm 以上 优秀 保持WiFi连接
-60dBm ~ -70dBm 良好 正常使用,开始监测
-70dBm ~ -80dBm 一般 准备切换,评估移动网络
-80dBm 以下 立即切换,避免丢包

我的经验:不要只看信号强度,还要看链路质量。我曾经遇到过信号强度-65dBm但丢包率高达30%的情况。建议结合WifiInfo.getRxSuccessRate()WifiInfo.getTxSuccessRate()做综合判断。

热点检测:别让用户连上「假WiFi」

热点检测,嗯,这里要注意。Android从9.0开始引入了WifiNetworkSuggestion机制,但很多厂商还是自己写了一套热点检测逻辑。我见过最离谱的是,某个ROM把隔壁奶茶店的WiFi识别成了「安全热点」,结果用户连上去后,所有流量都被劫持了。

热点检测的核心逻辑其实就三点:

  1. SSID白名单:系统预置的可信热点列表
  2. 证书验证:企业级热点需要验证CA证书
  3. 行为分析:检测热点是否有DNS劫持、ARP欺骗等行为

避坑指南:我曾经在某个项目里,把热点检测做得太严格了,结果用户连自家路由器都提示「不安全」。后来发现是路由器固件太老,不支持WPA3。所以建议在检测到不兼容时,给出降级提示而不是直接拒绝连接。

WiFi RTT定位:精度能到米级

WiFi RTT(Round Trip Time)定位,是Android 9引入的新特性。它不像传统RSSI定位那样靠信号强度估算距离,而是直接测量信号往返时间,精度能到1-2米。

我参与过一个商场导航项目,就是用WiFi RTT做的室内定位。效果确实比蓝牙要好,但有个前提——需要支持802.11mc的路由器。目前市面上支持的路由器还不多,这是个硬伤。

// WiFi RTT 定位示例
public class RttLocationHelper {
    private WifiRttManager rttManager;

    public void startRanging(List<ScanResult> apList) {
        RangingRequest.Builder builder = new RangingRequest.Builder();
        for (ScanResult ap : apList) {
            builder.addAccessPoint(ap);
        }
        RangingRequest request = builder.build();

        rttManager.startRanging(request, Runnable::run, new RangingResultCallback() {
            @Override
            public void onRangingResults(List<RangingResult> results) {
                for (RangingResult result : results) {
                    int distanceMm = result.getDistanceMm(); // 距离,单位毫米
                    int rssi = result.getRssi();
                    // 用距离做三角定位
                }
            }

            @Override
            public void onRangingFailure(int code) {
                // 处理失败情况
            }
        });
    }
}

关键点:WiFi RTT定位需要至少3个AP才能做三角定位。而且AP的位置要固定,不能是移动热点。另外,RTT测量结果会受到多径效应影响,建议做卡尔曼滤波平滑处理。

知识体系总览

下面这张图,是我自己整理的WiFi优化知识体系。你可以把它当作一个检查清单,看看自己的项目里哪些环节还没做到位。

WiFi 优化 扫描频率 限制第三方扫描 动态调整间隔 休眠时降频 网络切换 信号阈值判断 链路质量评估 平滑切换策略 热点检测 SSID白名单 证书验证 行为分析 RTT定位 802.11mc支持 三角定位算法 卡尔曼滤波 目标:低功耗 + 高体验 + 准定位

说实话,WiFi优化没有银弹。每个项目的情况都不一样,有的偏重功耗,有的偏重体验,有的偏重定位精度。我的建议是:先做数据采集,看看你的用户场景里,WiFi相关的痛点到底是什么,然后再对症下药。

好了,这一章的内容就到这里。如果你在实际项目中遇到了WiFi优化的具体问题,欢迎随时交流。


公众号:蓝海资料掘金营,微信deep3321