前言:
-
最近抽了一些下班后的时间,把项目里“网络状态判断”这块从零散业务代码中抽离出来,做成了一个可复用的 Flutter 插件:
network_quality_monitor。一开始目标很简单,只想知道当前是否联网,但真正落到项目后发现,业务侧更关心的是“当前网络到底好不好”。 -
所以这个插件最终不只做了连接状态,还补了网络类型识别、质量等级评估、实时监听,以及主动探测(RTT/下行估算)能力。这样页面可以基于网络质量做更细粒度的降级策略,而不是只用一个
isConnected硬判断。 -
本篇文章更偏实战一些,重点讲的是设计思路和落地方式,而不是单独讲 API。老规矩,先从整体思路开始。
正文:
当前项目中的 network_quality_monitor 使用,主要从下面几个维度来理解:
- 为什么要做网络质量监控插件
- 插件能力模型怎么设计
- Flutter 侧完整使用流程
- Android / iOS 原生实现思路
- 如何在业务页面做降级和兜底
- 常见误区和实践建议
-
为什么要做网络质量监控插件
在很多项目里,网络判断通常只有一句:
- 有网 / 没网
但真实业务里其实更复杂:
- 用户虽然“有网”,但 RTT 很高
- Wi-Fi 信号弱,接口频繁超时
- 蜂窝网络抖动,实时场景体验断续
- 前后台切换后网络能力变化很大
如果只靠 isConnected,页面只能做“是否可用”的粗判断。
而网络质量插件的目标是:
- 给业务侧提供可操作的质量信号
- 支持实时监听 + 主动探测
- 让页面可以按网络质量动态调整策略
比如:
-
质量差时降低图片质量
-
质量差时暂停大文件上传
-
实时场景下切换到低码率策略
-
插件能力模型设计
当前插件核心模型是 NetworkQualityStatus,包含:
isConnected:当前是否联网networkType:wifi / cellular / ethernet / none / other / unknownquality:offline / poor / fair / good / excellent / unknowndownlinkKbps:下行带宽估值(Android 有值,iOS 探测后可补)rttMs:往返时延(主动探测时返回)raw:原始结果透传(方便排障)
对应能力分为三类:
- 一次性查询:
getCurrentStatus() - 实时监听:
onStatusChanged - 主动探测:
probeQuality({probeUrl, timeoutMs})
这种设计有个好处:
- 业务可以按场景选择成本更低的能力
例如:
-
普通列表页只用
getCurrentStatus -
音视频页使用
onStatusChanged -
上传前调用一次
probeQuality -
Flutter 侧完整使用流程
下面以“页面进入后获取网络状态 + 开始监听 + 手动测速”这个常见场景举例。
final monitor = NetworkQualityMonitor();
// 1. 一次性获取当前状态
final current = await monitor.getCurrentStatus();
// 2. 监听网络变化
final sub = monitor.onStatusChanged.listen((status) {
// 根据质量动态调整 UI 或请求策略
// e.g. status.quality == NetworkQuality.poor
});
// 3. 业务关键时刻做主动探测(比如上传前)
final probe = await monitor.probeQuality(
probeUrl: 'https://www.baidu.com/favicon.ico',
timeoutMs: 1500,
);
// 页面销毁记得取消监听
sub.cancel();
如果你是 Store / ViewModel 架构,建议把监听和探测放在 store 里,页面只订阅状态。
-
Android 实现思路
Android 侧主要分两层:
- 被动监听能力:
ConnectivityManager + NetworkCallback - 主动探测能力:
HttpURLConnection计算 RTT,并结合带宽估值做质量判断
被动监听主要做:
- 网络可用变化
- 网络能力变化
- 网络类型变化
主动探测主要做:
- 对目标 URL 发起轻量请求
- 计算请求耗时作为
rttMs - 结合
downlinkKbps和rttMs生成质量等级
这两层组合起来,比单纯监听系统网络状态更贴近真实体验。
-
iOS 实现思路
iOS 侧基于:
NWPathMonitor:监听当前网络路径和类型URLSession:主动探测 RTT(必要时补充质量判断)
NWPathMonitor 非常适合做持续监听,但它不是完整测速工具。
所以在关键场景里配合一次 URLSession 探测,效果会更稳定。
也就是说:
-
被动监听负责“持续感知”
-
主动探测负责“关键时刻校准”
-
质量分级建议(可按业务调整)
当前插件是一个通用分级策略,建议你在业务里再做一层映射:
excellent:可开高质量能力(高清图、并发上传)good:默认策略fair:控制请求并发,减少预加载poor:启用保守策略(低清、延迟加载、弱网提示)offline:离线兜底
关键点是:
-
插件负责给“事实”
-
业务负责做“策略”
-
业务落地建议
如果你的页面依赖网络强度,建议这样组织:
- 页面初始化拿一次
getCurrentStatus - 页面可见期监听
onStatusChanged - 上传/实时前做
probeQuality - 把质量状态映射到统一降级策略
例如:
-
录音转写场景:
poor时降低帧率或提高重试间隔 -
图片流场景:
fair/poor时切换低清图源 -
下载场景:
poor时暂停后台预下载 -
常见误区
-
误区1:只用
isConnected判断体验
用户“有网”不代表可用体验好。建议至少结合 quality。
- 误区2:频繁主动探测
主动探测是有成本的,不建议高频调用。建议在关键操作前触发一次。
- 误区3:把策略写死在插件里
插件尽量做通用能力,业务策略放在项目层更灵活。
- 误区4:监听不释放
onStatusChanged 必须在页面/模块销毁时取消订阅。
-
项目中的架构总结
这轮改造后,网络质量相关逻辑已经形成了比较清晰的链路:
- 插件层提供统一网络状态能力
- store/viewmodel 负责组合与策略分发
- 页面按状态做局部刷新与降级提示
- 关键操作前用主动探测做校准
这样做的价值是:
- 多项目可复用
- 页面逻辑更轻
- 异常排查更直接
- 弱网场景体验更可控
结束:
网络质量监控这件事,真正有价值的点不在“拿到一个状态”,而在于:
- 能不能把网络变化转成业务可执行策略
- 能不能在关键场景前提前感知风险
- 能不能把弱网体验做成可控而不是被动兜底
这个插件目前已经具备基础可用能力,后续还可以继续做:
- 周期性探测
- 抖动估算
- 质量变化防抖
- 场景化策略模板
如果你项目里也有实时、上传、弱网敏感场景,建议尽早把“网络质量”从页面逻辑里抽出来,收益会比想象中大。
声明:
仅开源供大家学习使用,禁止从事商业活动,如出现一切法律问题自行承担。
仅学习使用,如有侵权,造成影响,请联系删除,谢谢。