Flutter如何全局检查网络连接并统一展示无网络页面
全局统一网络检测实现方案
核心思路
不用在每个页面重复堆网络判断的代码,直接在应用的根层级做一层统一的网络拦截,全局只监听一次网络状态,无网时直接在全屏盖一层无网提示页,有网就正常跑原来的所有业务逻辑,各个页面完全不用管网络检测的事。
具体实现步骤
1. 编写全局网络拦截组件
这个组件只负责两个事:全局监听网络状态变化、无网时在所有内容的最上层渲染无网页面,有网时完全不干扰原有应用逻辑。
class GlobalNetworkAwareWrapper extends StatelessWidget { // 传入原应用的根组件(也就是原来的MaterialApp) final Widget child; const GlobalNetworkAwareWrapper({super.key, required this.child}); @override Widget build(BuildContext context) { // 整个应用只订阅一次网络状态流,避免重复监听 final connectivityResult = context.watch<ConnectivityResult>(); final isOffline = connectivityResult == ConnectivityResult.none || connectivityResult == null; return Stack( children: [ // 原有业务页面正常渲染 child, // 无网时把无网页面盖在所有内容的最上层,拦截所有用户操作 if (isOffline) Positioned.fill( child: NoInternetScreen( // 无网页上的重试按钮逻辑可以直接在这里实现 onRetry: () { // 手动触发一次网络状态检测 InternetConnectionService().triggerConnectionCheck(); }, ), ) ], ); } }
2. 调整根组件的层级结构
把全局拦截组件挂载到应用最外层,处在StreamProvider和MaterialApp之间,保证能拿到全局的网络状态流,同时不破坏原有路由逻辑:
// 调整前的main.dart结构 // StreamProvider<ConnectivityResult>( // create: (context) => InternetConnectionService().connectionStatusController.stream, // child: MaterialApp(....) // ) // 调整后的main.dart结构 StreamProvider<ConnectivityResult>( create: (context) => InternetConnectionService().connectionStatusController.stream, child: GlobalNetworkAwareWrapper( child: MaterialApp( // 原有主题、路由、页面配置全部原样保留,无需改动 ...... ), ), )
3. 清理冗余的页面级逻辑
把每个页面里重复写的这些代码全部删掉即可:
- 页面里单独定义的
hasConnection状态变量 - 每个页面单独实现的
checkConnectivity方法 - build方法里的三元判断逻辑(
hasConnection == true ? Scaffold() : NoInternetScreen())
全局拦截层已经帮所有页面完成了无网判断,不会出现漏判的情况。
为什么这么写比逐页面判断靠谱
- 零业务侵入:所有业务页面不需要修改原有交互逻辑,只需要删除重复的网络检查代码即可
- 性能更优:全局只做一次网络状态监听,避免每个页面重复订阅状态、重复
setState带来的不必要重绘 - 体验更好:采用覆盖层的展示方式,不会因为网络中断就直接跳转到独立的无网页面,用户在业务页面填写的表单、列表滚动位置等状态都不会丢失,网络恢复后可以直接继续操作
- 无漏判风险:不管用户跳转多深的路由层级,只要处于无网状态,都会被统一拦截,不会出现某个页面忘记加判断就允许无网操作的问题
可选优化方向
- 原来逐页面在build方法里调用带setState的检查方法的写法本身就有重绘隐患,全局实现后可以直接清理这类冗余代码
- 如果需要在网络恢复/中断时给用户发轻量提示(比如顶部弹出的SnackBar),可以直接在
GlobalNetworkAwareWrapper里添加状态监听逻辑,不需要散落到各个页面实现 - 现有connectivity包仅检测设备是否连接网络(比如连了无网WiFi的场景),可以在
InternetConnectionService里补充简单的公网连通性检测,避免误判有网状态
内容的提问来源于stack exchange,提问作者Andreas Hunter
相关产品推荐
相关产品推荐

