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

Flutter应用切后台返回后InAppWebView冻结无响应问题

问题根因
  • 核心故障来自flutter_inappwebview在Android端开启HybridComposition渲染模式时的生命周期适配缺陷:应用切至后台停留数秒后,系统会回收WebView绑定的渲染Surface,切回前台时WebView未正确重建渲染层,直接导致渲染线程、输入事件队列阻塞,表现为页面冻结、网页无法滚动,甚至Flutter原生控件也无响应,必须杀进程重启才能恢复。
  • 现有代码存在逻辑bug:shouldOverrideUrlLoading回调中判断外链跳转时,错误引用了全局url变量,而非当前导航行为携带的目标地址,会导致外链跳转逻辑异常,极端场景下会触发路由死锁。
  • 代码未实现应用生命周期监听,切后台再恢复的场景下没有主动触发WebView的状态重置。
修复步骤
  1. 修复外链跳转逻辑错误
    找到shouldOverrideUrlLoading回调内的判断逻辑,将错误的全局url变量替换为当前导航的目标地址,修正后代码如下:
    shouldOverrideUrlLoading: (controller, navigationAction) async {
      var uri = navigationAction.request.url!;
    
      if (![ "http", "https", "file", "chrome",
        "data", "javascript", "about"].contains(uri.scheme)) {
        String targetUrl = uri.toString();
        if (await canLaunch(targetUrl)) {
          await launch(targetUrl);
          return NavigationActionPolicy.CANCEL;
        }
      }
    
      return NavigationActionPolicy.ALLOW;
    },
    
  2. 增加应用生命周期监听,切回前台时主动恢复WebView状态
    • 首先给_MyAppState类混入生命周期监听能力:将类定义从class _MyAppState extends State<MyApp>改为class _MyAppState extends State<MyApp> with WidgetsBindingObserver
    • 在initState方法中注册生命周期监听,在dispose方法中释放监听:
    @override
    void initState() {
      super.initState();
      WidgetsBinding.instance.addObserver(this);
      // 原有pullToRefreshController初始化逻辑保留
      pullToRefreshController = PullToRefreshController(
        options: PullToRefreshOptions(
          color: Colors.blue,
        ),
        onRefresh: () async {
          if (Platform.isAndroid) {
            webViewController?.reload();
          } else if (Platform.isIOS) {
            webViewController?.loadUrl(
                urlRequest: URLRequest(url: await webViewController?.getUrl()));
          }
        },
      );
    }
    
    @override
    void dispose() {
      WidgetsBinding.instance.removeObserver(this);
      super.dispose();
    }
    
    • 在State中新增生命周期回调方法,应用切回前台时主动触发WebView渲染层重建:
    @override
    void didChangeAppLifecycleState(AppLifecycleState state) async {
      // 仅处理Android端前台恢复场景,iOS无此问题
      if (state == AppLifecycleState.resumed && Platform.isAndroid && webViewController != null) {
        // 等待Flutter渲染树恢复完成后再操作WebView,避免时序问题
        await Future.delayed(const Duration(milliseconds: 100));
        // 触发WebView渲染层重建
        webViewController?.android?.resumeTimers();
        webViewController?.reload();
      }
    }
    
  3. 可选兼容配置
    如果上述方案在部分定制ROM上仍偶现卡死,可以修改AndroidManifest.xml中MainActivity的启动模式,不要使用singleInstance,改为默认的standard或singleTop即可;如果仍有问题,可以临时将Android端WebView配置中的useHybridComposition: true改为false,使用虚拟渲染模式规避Surface回收问题,注意该模式在部分机型上可能出现WebView内输入框焦点异常,优先使用生命周期恢复方案。
验证方式
  • 启动应用确认网页加载、滚动、底部导航按钮点击均正常
  • 切换到其他应用停留5-10秒,可打开多个内存占用较高的应用触发系统资源回收
  • 切回原应用,确认网页可正常滚动、控件响应正常,无需重启即可使用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 02:15:38