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

Flutter中InAppWebView跳转第三方App不稳定问题求助

解决方案:修复InAppWebView跳转第三方App不稳定问题

问题根源

你遇到的跳转偶尔失效,核心原因是await controller.stopLoading()与shouldOverrideUrlLoading的返回策略冲突:返回NavigationActionPolicy.CANCEL本身就会阻止WebView加载目标URL,提前调用stopLoading会打断Intent解析或App启动的异步流程,导致时序混乱。

具体修改方案

  1. 移除冗余的stopLoading调用:用返回CANCEL替代手动停止加载,避免时序冲突
  2. 修复Android端重复启动逻辑:原代码中重复调用launchUrl会导致不必要的重复操作
  3. 完善启动失败的 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,提问作者김민경

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 16:35:07