Flutter中InAppWebView跳转第三方App不稳定问题求助
解决方案:修复InAppWebView跳转第三方App不稳定问题
问题根源
你遇到的跳转偶尔失效,核心原因是await controller.stopLoading()与shouldOverrideUrlLoading的返回策略冲突:返回NavigationActionPolicy.CANCEL本身就会阻止WebView加载目标URL,提前调用stopLoading会打断Intent解析或App启动的异步流程,导致时序混乱。
具体修改方案
- 移除冗余的
stopLoading调用:用返回CANCEL替代手动停止加载,避免时序冲突 - 修复Android端重复启动逻辑:原代码中重复调用
launchUrl会导致不必要的重复操作 - 完善启动失败的 fallback 处理:当无法打开第三方App时,允许WebView继续加载URL,保障用户操作路径
修改后的核心代码
shouldOverrideUrlLoading: (controller, navigationAction) async { final curUrl = navigationAction.request.url; if (curUrl == null) return NavigationActionPolicy.CANCEL; final ru = Uri.decodeComponent(curUrl.toString()); final isAppLink = _isAppLink(curUrl); if (isAppLink) { if (Uri.parse(ru).scheme == 'intent') { if (Platform.isAndroid) { final uriAndroid = UriExtension.androidIntentUrlOrigin(ru); if (await canLaunchUrl(uriAndroid)) { await launchUrl(uriAndroid); // 启动成功则阻止WebView加载 return NavigationActionPolicy.CANCEL; } // 启动失败则允许WebView继续加载,作为fallback return NavigationActionPolicy.ALLOW; } } else { if (Platform.isIOS) { const allowedSchemes = ["http", "https", "file", "chrome", "data", "javascript", "about"]; if (!allowedSchemes.contains(curUrl.scheme)) { if (await canLaunchUrl(curUrl)) { await launchUrl(curUrl); return NavigationActionPolicy.CANCEL; } } return NavigationActionPolicy.ALLOW; } } // 默认阻止加载,除非启动失败已返回ALLOW return NavigationActionPolicy.CANCEL; } else { return NavigationActionPolicy.ALLOW; } }, // 优化isAppLink判断逻辑,避免误判 bool _isAppLink(Uri url) { final appScheme = url.scheme; if (Platform.isIOS) { return !['http', 'https', 'about', 'data'].contains(appScheme); } else { return !['http', 'https', 'about:blank', 'data'].contains(appScheme); } }
额外优化点
- 移除
onLoadResourceCustomScheme中的await controller.stopLoading(),该回调返回null会自动处理自定义Scheme,手动停止加载可能干扰正常流程 - 原
onLoadStop中直接解析页面文本的逻辑存在风险,建议后端通过JSBridge传递支付结果,避免依赖页面DOM内容解析
内容的提问来源于stack exchange,提问作者김민경
相关产品推荐
相关产品推荐

