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

Flutter中InAppWebView内showDialog的BuildContext异步间隙警告解决方法

解决Flutter中InAppWebView内showDialog的「Don't use 'BuildContext' across async gaps」警告

这个警告的核心原因是:await异步操作完成后,当前Widget可能已经被销毁(比如用户跳转了页面),此时继续使用原context会导致无效状态,甚至引发崩溃。下面是几种实用的解决方法:

方法一:利用State的mounted属性检查(推荐)

如果你的组件是StatefulWidget,直接在异步操作后判断当前State是否仍处于挂载状态,再执行showDialog:

return InAppWebView(
  ...
  onLongPressHitTestResult: (controller, hitTestResult) async {
    if (LongPressAlertDialog.hitTestResultSupported.contains(hitTestResult.type)) {
      var requestFocusNodeHrefResult = await _webViewController?.requestFocusNodeHref();

      // 先确认当前Widget还没被销毁
      if (!mounted) return;

      if (requestFocusNodeHrefResult != null) {
        showDialog(
          context: context,
          builder: (context) {
            return LongPressAlertDialog(
              webViewModel: widget.webViewModel,
              hitTestResult: hitTestResult,
              requestFocusNodeHrefResult: requestFocusNodeHrefResult,
            );
          },
        );
      }
    }
  },
);

方法二:使用GlobalKey获取有效Context

如果是StatelessWidget,或者不想依赖State的mounted,可以通过GlobalKey持有父Widget的有效Context:

  1. 在Widget类中定义GlobalKey:
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
  1. 在父Scaffold中绑定Key:
return Scaffold(
  key: _scaffoldKey,
  body: InAppWebView(
    ...
    onLongPressHitTestResult: (controller, hitTestResult) async {
      if (LongPressAlertDialog.hitTestResultSupported.contains(hitTestResult.type)) {
        var requestFocusNodeHrefResult = await _webViewController?.requestFocusNodeHref();

        if (requestFocusNodeHrefResult != null && _scaffoldKey.currentContext != null) {
          showDialog(
            context: _scaffoldKey.currentContext!,
            builder: (context) {
              return LongPressAlertDialog(
                webViewModel: widget.webViewModel,
                hitTestResult: hitTestResult,
                requestFocusNodeHrefResult: requestFocusNodeHrefResult,
              );
            },
          );
        }
      }
    },
  ),
);

方法三:结合根Navigator的Context

如果担心Context层级问题,可以直接获取根Navigator的Context,同时配合mounted检查:

if (!mounted) return;
showDialog(
  context: Navigator.of(context, rootNavigator: true),
  builder: (context) {
    return LongPressAlertDialog(
      webViewModel: widget.webViewModel,
      hitTestResult: hitTestResult,
      requestFocusNodeHrefResult: requestFocusNodeHrefResult,
    );
  },
);

总结

优先使用方法一,这是Flutter官方推荐的方案,逻辑简单且能有效规避无效Context的风险。如果是无状态组件场景,再考虑GlobalKey的方式。

内容的提问来源于stack exchange,提问作者ayushkadbe

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 02:55:39