性能优化:扫描间隔控制、连接速度优化、内存与 CPU 占用

Wi-Fi 性能优化,说白了就是让系统跑得又快又稳。我见过不少项目,功能都做全了,但一跑起来手机发烫、电量狂掉。用户可不管你是不是功能完整,卡顿就是原罪。

今天咱们就聊聊三个核心方向:扫描间隔怎么控、连接速度怎么提、内存和 CPU 怎么省。嗯,这些都是我在实际项目中踩过的坑。

扫描间隔控制:别让 Wi-Fi 像个永动机

Wi-Fi 扫描是个耗电大户。你想想看,每次扫描都要唤醒天线、监听信道、解析 beacon 帧。如果扫描太频繁,电池扛不住。但如果扫描间隔太长,用户又觉得 Wi-Fi 反应慢。

核心原则:按需扫描,动态调整。

我个人习惯把扫描场景分成三类:

  • 前台场景:用户正在操作 Wi-Fi 界面,或者正在连接网络。这时候需要快速响应,扫描间隔可以短到 3-5 秒。
  • 后台场景:应用在后台运行,或者屏幕关闭。这时候可以拉长到 30-60 秒,甚至更久。
  • 漫游场景:设备在移动中,信号强度在下降。这时候需要主动触发扫描,而不是等固定间隔。

避坑指南:我曾经在一个项目中,把后台扫描间隔设成了 10 秒。结果用户反馈手机半天就没电了。后来一查,Wi-Fi 扫描占了 30% 的耗电。改成 60 秒后,问题直接解决。

代码实现上,我建议用 WifiManager.startScan() 配合定时器,而不是依赖系统默认的扫描周期。这样你可以根据场景动态调整:

// 动态扫描间隔示例
private static final long SCAN_INTERVAL_FOREGROUND = 5_000L;  // 5秒
private static final long SCAN_INTERVAL_BACKGROUND = 60_000L; // 60秒

private void scheduleScan(long interval) {
    mHandler.removeCallbacks(mScanRunnable);
    mHandler.postDelayed(mScanRunnable, interval);
}

private final Runnable mScanRunnable = new Runnable() {
    @Override
    public void run() {
        mWifiManager.startScan();
        // 根据当前场景决定下一次扫描间隔
        long nextInterval = isForeground() ? 
            SCAN_INTERVAL_FOREGROUND : SCAN_INTERVAL_BACKGROUND;
        scheduleScan(nextInterval);
    }
};

连接速度优化:从扫描到连上,能多快就多快

用户最烦的是什么?点开 Wi-Fi 列表,等半天才看到网络列表。选了个网络,又等半天才连上。这体验,说实话挺糟糕的。

连接速度优化,我总结了三板斧:

  1. 缓存已知网络:别每次都全量扫描。如果用户之前连过某个网络,直接缓存它的 BSSID、信道、加密方式。下次连接时,优先尝试缓存的信息。
  2. 并行扫描与认证:扫描和认证可以同时进行。我记得在 Android 8.0 之后,系统支持了 WifiNetworkSpecifier,可以提前指定网络参数,跳过扫描阶段。
  3. 减少不必要的信令交互:DHCP 协商、4-way handshake 这些步骤,能省则省。比如用静态 IP 代替 DHCP,或者缓存 PMKID 避免重复认证。

小技巧:我习惯在 WifiManagerCONNECT_NETWORK 回调中,直接监听 SUPPLICANT_STATE_CHANGE_ACTION。这样能第一时间知道连接状态,不用等系统广播绕一圈。

来看一个实际优化案例。有一次,我发现某个设备连接企业级 Wi-Fi 特别慢,每次都要 8-10 秒。后来定位到是 EAP 认证时,证书验证花了太多时间。优化方案是缓存 CA 证书的哈希值,避免每次都重新解析:

// 缓存 EAP 证书信息,加速重连
private static final String CACHED_CA_HASH = "sha256/...";

private boolean verifyCachedCertificate(X509Certificate cert) {
    String hash = computeHash(cert.getEncoded());
    return CACHED_CA_HASH.equals(hash);
}

优化后,连接时间降到了 2-3 秒。用户反馈明显变好了。

内存与 CPU 占用:别让 Wi-Fi 服务成为性能杀手

Wi-Fi Service 跑在系统进程中,如果它占用了太多内存或 CPU,整个系统都会变慢。我见过最夸张的情况,Wi-Fi 进程占用了 200MB 内存,导致系统频繁触发 low memory killer。

内存优化要点:

  • 避免大对象常驻:比如扫描结果列表,每次扫描后及时清理旧数据。我习惯用 WeakReference 来持有扫描结果,避免强引用导致内存泄漏。
  • 复用对象:像 ScanResultWifiConfiguration 这些对象,能复用就复用。别每次 new 一个新的。
  • 延迟加载:有些数据不是一开始就需要。比如网络历史记录,可以等用户打开 Wi-Fi 设置页面时再加载。

CPU 优化要点:

  • 减少轮询:能用回调就别用轮询。比如监听 RSSI_CHANGED_ACTION 代替定时检查信号强度。
  • 批量处理:如果有多个网络需要连接,别一个一个来。批量提交给 supplicant,让它自己调度。
  • 异步处理:耗时的操作(比如 DHCP、DNS 查询)放到后台线程。别在主线程里等。

注意:我曾经在优化 CPU 占用时,把扫描结果的处理放到了 AsyncTask 里。结果因为线程池太小,导致扫描结果处理排队,反而更慢了。后来改用 HandlerThread 单独开一个线程,才解决问题。

下面这张图是我自己总结的 Wi-Fi 性能优化整体框架,你可以参考一下:

Wi-Fi 性能优化框架 扫描间隔控制 连接速度优化 内存与CPU优化 前台场景:3-5秒 后台场景:30-60秒 漫游场景:主动触发 缓存已知网络信息 并行扫描与认证 减少信令交互 避免大对象常驻 减少轮询,多用回调 异步处理耗时操作 目标:流畅体验 + 低功耗 + 低资源占用

实战中的取舍

说实话,性能优化没有银弹。你不可能同时做到扫描最快、连接最快、资源占用最低。关键是根据产品定位做取舍。

举个例子:

  • 如果是 手机,电池续航优先,扫描间隔可以拉长。
  • 如果是 智能家居设备,连接速度优先,可以牺牲一点功耗。
  • 如果是 车载系统,稳定性优先,内存占用要严格控制。

我个人的经验是:先定指标,再优化。比如设定「扫描到连接完成不超过 3 秒」、「Wi-Fi 进程内存占用不超过 50MB」、「CPU 占用率不超过 5%」。有了明确的目标,优化起来才有方向。

最后说一句:性能优化是个持续的过程。别指望一次改完就万事大吉。上线后多看看日志,多听听用户反馈。有时候一个小改动,就能带来质的提升。


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