Flutter多WebView组件报错:Bad state: Future already completed
解决"Bad state: Future already completed"异常问题
这个问题的根源非常明确:你把_controller这个Completer对象定义成了全局变量,所有PageWeb实例都会共享同一个Completer实例。
当第一个Tab的WebView完成初始化时,_controller.complete(webViewController)已经将这个Completer标记为"已完成"状态;当你切换到第二个Tab,第二个PageWeb的WebView尝试再次调用_controller.complete()时,就会触发异常——因为一个Completer对象只能被完成一次,不允许重复调用complete方法。
修复方案
把Completer<WebViewController>的定义移到_PageWebState类内部,让每个PageWeb实例都拥有自己独立的Completer:
修改你的pageweb.dart代码如下:
class PageWeb extends StatefulWidget { final delegate; final ObjectKey key; final String navTitle; PageWeb(this.delegate, this.key, this.navTitle); @override _PageWebState createState() { return _PageWebState(); } } class _PageWebState extends State<PageWeb> { bool _isLoading = true; final cookieManager = WebviewCookieManager(); // 将Completer移到State内部,每个PageWeb实例独立持有 final Completer<WebViewController> _controller = Completer<WebViewController>(); @override Widget build(BuildContext context) { return CupertinoPageScaffold( navigationBar: CupertinoNavigationBar( middle: Text(widget.navTitle), ), child: SafeArea( child: Container( child: WebView( key: widget.key, initialUrl: "https://www.google.com/search?q=${widget.navTitle}", javascriptMode: JavascriptMode.unrestricted, onWebViewCreated: (WebViewController webViewController) { _controller.complete(webViewController); // 现在每个实例用自己的Completer,不会重复完成 }, onPageStarted: (String pageUrl) { setState(() { _isLoading = true; }); }, onPageFinished: (String pageUrl) { setState(() { _isLoading = false; }); }, )))); } }
额外优化(可选)
如果你的父组件(_MyHomePageState)需要获取每个WebView的控制器,可以在PageWeb中暴露Future<WebViewController>的方式实现,比如:
class PageWeb extends StatefulWidget { // ... 现有代码 // 添加getter让父组件可以获取controller的Future Future<WebViewController> get controller => _state._controller.future; _PageWebState _state; @override _PageWebState createState() { _state = _PageWebState(); return _state; } }
这样父组件就可以通过pageA.controller来获取对应WebView的控制器,同时也不会影响每个Tab的独立初始化流程。
内容的提问来源于stack exchange,提问作者klados
相关产品推荐
相关产品推荐

