uni.onNetworkStatusChange 是 App 端检测网络状态变化的唯一可靠入口,但需自行处理防抖、权限、上下文丢失等问题;它仅在系统网络栈切换时触发,非轮询,且在 iOS 后台、Android 定制 ROM 等场景易失效。

uni.onNetworkStatusChange 是 App 端检测网络状态变化的唯一可靠入口,但它不等于“断网提醒”开箱即用——你得自己处理 isConnected: false 的触发时机、防抖、页面上下文丢失、以及真机权限缺失等实际问题。
uni.onNetworkStatusChange 为什么在App里有时不触发
它只在系统网络栈真正切换时回调,不是轮询。常见失效场景:
- App 启动后没调用
onShow就直接进页面,监听未注册(必须在onShow中注册才稳定) - iOS 真机调试未开启「后台运行」权限,切到桌面后监听立即失效
- Android 某些定制 ROM(如华为 EMUI)会限制后台网络广播,需手动在 manifest 中补
android.permission.ACCESS_NETWORK_STATE - WiFi 已连接但 DHCP 还没分配 IP,
isConnected仍为false,此时用户看到的是“断网”,其实只是延迟
如何避免“断网弹窗狂轰滥炸”
网络抖动(比如地铁穿隧道)会导致 isConnected 在 true/false 间快速跳变,直接弹窗会把用户吓退。实操建议:
- 加 1.5 秒防抖:用
setTimeout缓存上一次isConnected值,仅当连续 2 次为false才触发提醒 - 限制单日弹窗次数(例如最多 3 次),用
uni.getStorageSync('offline_count')+ 时间戳判断 - 只在当前页面是活跃页(
getCurrentPages().pop()?.route === 'pages/xxx')时才 showToast,避免后台页误触 - 别用
uni.showModal做首次断网提示——阻塞操作,用户点“确定”前无法做任何事;优先用uni.showToast或顶部 banner
uni.getNetworkType 能否替代实时监听
不能。它是快照,适合页面加载时兜底判断,但有明显缺陷:
- 冷启动时安卓部分机型返回
unknown(网络栈未就绪) - iOS 在无网络下可能卡住 2–3 秒才回调,导致页面白屏等待
- 即使返回
wifi,也不代表能通外网(比如公司内网 WiFi 无公网出口) - 必须搭配
uni.onNetworkStatusChange使用:前者做初始状态,后者做持续响应
推荐组合写法:uni.getNetworkType 获取初始值 → 存入全局 Vue.prototype.$network → 在 onShow 中注册 uni.onNetworkStatusChange 更新该值 → 所有页面 watch 它即可响应
断网后要不要自动重试请求
不要无条件重试。真实项目中容易忽略的关键点:
- 断网期间积压的请求(比如离线提交的表单)应进队列,但需标记时间戳,超 5 分钟未恢复则丢弃,避免网络恢复后集中爆发请求打崩服务端
- 重试逻辑必须和具体 API 绑定,而不是全局拦截 —— 登录接口断网后重试有意义,但上传大文件中途断网再重试大概率失败
- H5 环境下
uni.onNetworkStatusChange不工作,必须 fallback 到navigator.onLine+ 定期uni.request心跳探测(如每 15 秒 GET /health) - App 后台被杀后重启,之前监听已丢失,需在
onLaunch和onShow都重新注册监听
最常被绕过的细节是:iOS 上用户手动关闭 WiFi 开关后,isConnected 可能延迟 1–2 秒才变为 false;而 Android 某些厂商(如小米)会在省电模式下直接禁掉网络状态广播 —— 这时候你得靠心跳请求兜底,不能只信 API 返回值。











