uni.onNetworkStatusChange能监听网络连接状态(isConnected)和类型(WiFi/4G/5G),不能监听SSID、信号强度、具体热点名称;仅在前台生效,需正确配置权限与生命周期绑定。
uni.onNetworkStatusChange 能监听什么,不能监听什么
它能实时告诉你设备“有没有连上网络”,以及“当前走的是 wifi 还是 4g/5g”,但不会主动告诉你 wifi 名(ssid)、信号强度、是否连上了特定热点。这是很多开发者一开始的误解——以为开了监听就能拿到公司 wifi 的名字,结果 res.networktype 是 wifi,但下一步想校验是不是“office-2f”就卡住了。
它的触发时机很实在:只有当系统网络栈真正切换时才触发,比如从 WiFi 断开→自动切到 5G,或插上 USB 网络共享。但注意:WiFi 连接成功但尚未获取 IP(比如 DHCP 卡住),isConnected 仍为 false;同样,WiFi 已断开但系统缓存还没刷新,也可能短暂维持 isConnected: true。
- 只在 App 前台生效(
onShow中注册最稳妥) - iOS 和 Android 行为一致,但真机调试必须开启「后台运行」权限,否则切到桌面就收不到回调
- 微信小程序不支持该 API,H5 环境下始终返回
unknown,别在浏览器里测这个逻辑
怎么用 uni.getNetworkType 做首次判断 + 防抖容错
它是一次性快照,适合页面加载时兜底判断。但直接写在 onLoad 里容易踩两个坑:一是某些安卓机型冷启动时网络栈未就绪,返回 unknown;二是 iOS 在无网络时可能延迟返回,造成白屏等待。
实操建议是加一层简单状态管理 + 超时兜底:
let networkCheckTimer = null;
function checkInitialNetwork() {
clearTimeout(networkCheckTimer);
uni.getNetworkType({
success: (res) => {
handleNetworkChange({ isConnected: res.networkType !== 'none', networkType: res.networkType });
},
fail: () => {
// 失败不等于没网,可能是权限/系统忙,先按“未知”处理
handleNetworkChange({ isConnected: false, networkType: 'unknown' });
}
});
// 800ms 后强制 fallback,避免阻塞 UI
networkCheckTimer = setTimeout(() => {
handleNetworkChange({ isConnected: false, networkType: 'unknown' });
}, 800);
}
-
handleNetworkChange应统一处理 UI 提示、本地存储(如uni.setStorageSync('onLine_status', 'onLine'))、接口重试开关 - 不要在
fail回调里直接弹 Toast,用户还没看清页面就弹窗体验很差 - H5 下永远走
fail,可提前用navigator.onLine做轻量 fallback
离线时跳转系统设置,iOS 和 Android 处理差异很大
iOS 上 uni.openSetting() 只能打开通用设置页,无法直达「Wi-Fi」子页;而 Android 没有标准跳转方式,各厂商路径不一(华为是 package:com.android.settings,小米要进「WLAN」二级菜单),强行适配反而容易崩溃。
更务实的做法是分层引导:
- 检测到
networkType === 'none'时,先展示清晰提示:“当前无网络连接,请检查 Wi-Fi 或蜂窝数据” - 按钮文案写“去设置”,点击后 iOS 调用
uni.openSetting(),Android 直接uni.showToast({ title: '请手动打开网络' }) - 绝对不要尝试用
plus.runtime.launchApplication或 deep link 拼 URL,iOS 14+ 会静默失败,Android 12+ 权限收紧后基本不可用
为什么你监听了却收不到回调?三个高频漏点
不是 API 失效,而是环境或写法卡住了。最常被忽略的三点:
-
uni.onNetworkStatusChange必须在onShow中注册,且对应在onHide中调用uni.offNetworkStatusChange()—— 否则多次进入页面会重复监听,导致回调执行多遍 - Android 10+ 需要在
manifest.json里显式声明"android.permission.ACCESS_NETWORK_STATE",缺了这句,真机上监听直接静默失效 - iOS 真机需确认 Xcode 工程中
Info.plist是否包含NSLocalNetworkUsageDescription(即使不用 Bonjour,部分 iOS 版本也会因缺失此字段导致网络事件不触发)
这些配置项不报错、不警告,只让监听“看起来没反应”。遇到这种情况,先查配置,再查生命周期绑定,最后才怀疑代码逻辑。










