如何在Dio拦截器中显示API错误提示Alert Dialog
在Dio拦截器中显示错误提示AlertDialog的实现方案
要在Dio拦截器里触发AlertDialog,核心问题是拦截器无法直接获取BuildContext,下面是两种可行的实现方式:
方案一:使用全局导航键(GlobalKey)
这是最直接的方式,通过全局维护的导航键获取上下文来弹出对话框。
步骤1:定义全局导航键
在项目的全局位置(比如main.dart顶部)定义导航键:
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
步骤2:配置MaterialApp的导航键
在MaterialApp中绑定这个全局键:
MaterialApp( navigatorKey: navigatorKey, title: 'Your App', home: const HomePage(), );
步骤3:修改Dio拦截器代码
在拦截器中通过全局键获取上下文并弹出对话框,同时处理空安全:
class HttpCustomClient { static Dio configureDio() { final dio = Dio(); dio.options.baseUrl = AppConsts.baseUrl; dio.interceptors.add(InterceptorsWrapper(onError: ((exception, handler) { // 先判断response是否存在,避免空指针 if (exception.response != null) { var errorText = exception.response!.data['error'] ?? '请求失败,请稍后重试'; // 确保上下文已初始化 if (navigatorKey.currentContext != null) { showDialog( context: navigatorKey.currentContext!, barrierDismissible: false, builder: (context) => AlertDialog( title: const Text('错误提示'), content: Text(errorText), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: const Text('确定'), ), ], ), ); } } return handler.next(exception); }))); return dio; } }
方案二:使用状态管理(以ChangeNotifier为例)
适合复杂项目,通过状态管理传递错误信息,让UI层主动监听并弹出对话框,解耦拦截器与UI逻辑。
步骤1:创建错误状态管理类
class ErrorNotifier extends ChangeNotifier { String? _errorMessage; String? get errorMessage => _errorMessage; void setError(String message) { _errorMessage = message; notifyListeners(); } void clearError() { _errorMessage = null; } }
步骤2:在全局提供状态实例
在main.dart中通过Provider注入状态:
void main() { runApp( ChangeNotifierProvider( create: (context) => ErrorNotifier(), child: const MyApp(), ), ); }
步骤3:修改Dio拦截器传递错误
将状态实例传入拦截器,触发错误通知:
class HttpCustomClient { static Dio configureDio(ErrorNotifier errorNotifier) { final dio = Dio(); dio.options.baseUrl = AppConsts.baseUrl; dio.interceptors.add(InterceptorsWrapper(onError: ((exception, handler) { if (exception.response != null) { var errorText = exception.response!.data['error'] ?? '请求失败,请稍后重试'; errorNotifier.setError(errorText); } return handler.next(exception); }))); return dio; } }
步骤4:在UI层监听错误并弹出对话框
在主页面或基页面中监听状态变化:
class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { final errorNotifier = Provider.of<ErrorNotifier>(context); // 利用PostFrameCallback确保UI渲染完成后再弹框 WidgetsBinding.instance.addPostFrameCallback((_) { if (errorNotifier.errorMessage != null) { showDialog( context: context, barrierDismissible: false, builder: (context) => AlertDialog( title: const Text('错误提示'), content: Text(errorNotifier.errorMessage!), actions: [ TextButton( onPressed: () { Navigator.pop(context); errorNotifier.clearError(); }, child: const Text('确定'), ), ], ), ); } }); return Scaffold( appBar: AppBar(title: const Text('主页')), body: const Center(child: Text('页面内容')), ); } }
注意事项
- 全局导航键方式要注意:app启动初期
navigatorKey.currentContext可能为空,必须加非空判断。 - 状态管理方式更适合多页面场景,能统一处理错误逻辑,避免全局键带来的耦合问题。
- 处理API错误时,要覆盖无response的情况(比如网络断开),避免空指针异常。
内容的提问来源于stack exchange,提问作者Osama El-Masri
相关产品推荐
相关产品推荐

