You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 04:00:34