网络恢复后无法自动加载数据,Flutter BLOC问题求助
网络恢复后数据无法自动加载的问题排查与修复
问题概述
已实现网络连接检测功能,但断网后ErrorBloc捕获到错误,恢复网络后数据无法自动加载,必须热重启才能正常加载;恢复网络后错误状态持续存在,页面一直显示错误组件。
核心问题分析
- ErrorBloc状态未重置:网络恢复时没有触发事件清除
ErrorBloc的ShowErrorState,导致错误组件一直显示。 - Connectivity监听逻辑不全:仅在网络切换为
mobile时触发LoadListEvent,漏掉了wifi场景;且事件发送顺序不合理,可能导致状态更新混乱。 - 网络请求异常未处理:
PagBloc中调用apiService.getResult时未捕获异常,若恢复网络后请求失败,错误状态会持续保留。 - 状态发射顺序冲突:
_onLoadData方法中最后一次emit会覆盖之前的连接状态更新,导致状态不一致。
修复方案
1. 完善Connectivity监听逻辑
在HomePage的initState中补全网络类型判断,同时在网络恢复时先重置ErrorBloc状态:
@override void initState() { super.initState(); final homeBloc = BlocProvider.of<HomeBloc>(context); final errorBloc = BlocProvider.of<ErrorBloc>(context); homeBloc.add(LoadListEvent()); Connectivity().onConnectivityChanged.listen((ConnectivityResult result) { if (result != ConnectivityResult.none) { // 网络恢复:先清除错误状态,再触发数据加载 errorBloc.add(HideErrorEvent()); homeBloc.add(LoadListEvent()); } else { homeBloc.add(NoInternetEvent(result)); errorBloc.add(ShowErrorEvent(message: "无网络连接")); } }); }
2. 处理PagBloc中的请求异常
在_checkConnection和_onLoadData中添加异常捕获,确保请求失败时能正确处理状态:
_checkConnection(NoInternetEvent event, Emitter<PagState> emit) async { if (event.result == ConnectivityResult.mobile || event.result == ConnectivityResult.wifi) { try { final newData = await apiService.getResult(1, state.count); emit(state.copyWith(connection: true, result: newData.results)); // 成功加载后清除错误状态 BlocProvider.of<ErrorBloc>(context).add(HideErrorEvent()); } catch (e) { emit(state.copyWith(connection: false)); BlocProvider.of<ErrorBloc>(context).add(ShowErrorEvent(message: e.toString())); } } else { emit(state.copyWith(connection: false)); } } void _onLoadData(LoadListEvent event, Emitter<PagState> emit) async { final bool isInternetConnected = await isInternetAvailable(); List<ResultModel> data = []; bool isCached = false; if (isInternetConnected) { try { const nextPage = 1; final newData = await apiService.getResult(nextPage, state.count); await service.insertPaginatedList(newData.results); data = newData.results ?? []; isCached = false; emit(state.copyWith( connection: true, result: data, page: nextPage, isCached: isCached, )); BlocProvider.of<ErrorBloc>(context).add(HideErrorEvent()); } catch (e) { // 请求失败时读取缓存 final cachedData = await service.getCachedList(); data = cachedData ?? []; isCached = true; emit(state.copyWith( connection: false, result: data, page: state.page, isCached: isCached, )); BlocProvider.of<ErrorBloc>(context).add(ShowErrorEvent(message: e.toString())); } } else { final cachedData = await service.getCachedList(); data = cachedData ?? []; isCached = true; emit(state.copyWith( connection: false, result: data, page: state.page, isCached: isCached, )); BlocProvider.of<ErrorBloc>(context).add(ShowErrorEvent(message: "无网络连接")); } }
3. 同时监听ErrorBloc和HomeBloc状态
使用MultiBlocBuilder同时监听两个Bloc的状态,确保数据更新时页面能同步刷新:
body: MultiBlocBuilder( builders: [ BlocBuilder<ErrorBloc, ErrorState>(builder: (context, state) => state), BlocBuilder<HomeBloc, PagState>(builder: (context, state) => state), ], builder: (context, states) { final errorState = states[0] as ErrorState; final pagState = states[1] as PagState; if (errorState is ShowErrorState) { return ErrorTextWidget(message: errorState.message); } else { // 渲染列表内容 return ListView.builder( itemCount: pagState.result.length, itemBuilder: (context, index) { return ListTile(title: Text(pagState.result[index].title)); // 根据实际Model字段调整 }, ); } }, ),
4. 确保ErrorBloc支持状态重置
在ErrorBloc中添加HideErrorEvent对应的处理逻辑:
class ErrorBloc extends Bloc<ErrorEvent, ErrorState> { ErrorBloc() : super(InitialErrorState()) { on<ShowErrorEvent>((event, emit) => emit(ShowErrorState(message: event.message))); on<HideErrorEvent>((event, emit) => emit(InitialErrorState())); } } // 补充事件定义 abstract class ErrorEvent {} class ShowErrorEvent extends ErrorEvent { final String message; ShowErrorEvent({required this.message}); } class HideErrorEvent extends ErrorEvent {} // 补充状态定义 abstract class ErrorState {} class InitialErrorState extends ErrorState {} class ShowErrorState extends ErrorState { final String message; ShowErrorState({required this.message}); }
内容的提问来源于stack exchange,提问作者user16357470
相关产品推荐
相关产品推荐

