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

Android和iOS端App后台恢复后InAppWebView出现白屏问题

问题描述

当我关闭应用约一分钟后将其切换到后台,再恢复应用时,InAppWebView组件被白色遮罩覆盖,或无法显示网页内容。我仍可与应用暂停前加载的页面交互,也能听到网站音效,说明页面仍在运行,但不知如何让恢复时页面正常显示。调试控制台无异常输出,与InAppWebView正常显示时一致。

我尝试过实现基础版InAppWebView、更换URL、执行flutter clean、flutter pub upgrade和flutter pub downgrade,问题仍存在。

页面代码

class CustomWebView extends StatefulWidget {
  final String url;

  CustomWebView({required this.url});

  @override
  _CustomWebViewState createState() => _CustomWebViewState();
}

class _CustomWebViewState extends State<CustomWebView>
    with SingleTickerProviderStateMixin, WidgetsBindingObserver {
  bool _isLoading = true; // Initially, webview is loading
  late InAppWebViewController webcontroller;

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return InAppWebView(
      key: Key('webview'),
      initialOptions: InAppWebViewGroupOptions(
        crossPlatform: InAppWebViewOptions(
          transparentBackground: true,
          useShouldOverrideUrlLoading: true,
          supportZoom: true,
        ),
        android: AndroidInAppWebViewOptions(
          builtInZoomControls: true,
          loadWithOverviewMode: true,
          useWideViewPort: true,
        ),
        ios: IOSInAppWebViewOptions(
          disableInputAccessoryView: true,
          allowsInlineMediaPlayback: true,
        ),
      ),
      initialUrlRequest: URLRequest(url: Uri.parse(widget.url)),
      shouldOverrideUrlLoading: (controller, navigationAction) async {
        var uri = navigationAction.request.url!;
        if (uri.toString().contains('logout')) {
          logOut(context);
          return NavigationActionPolicy.CANCEL;
        }
        if (uri.toString().contains('whatsapp')) {
          var shareText = await getTextParam(uri.toString());
          Share.share(shareText!);
          return NavigationActionPolicy.CANCEL;
        }
        if (uri.toString().contains('?process_s=3')) {
          var status = await Permission.storage.status;
          if (!status.isGranted) {
            status = await Permission.storage.request();
          }
          if (status.isGranted) {
            Navigator.push(
                context,
                MaterialPageRoute(
                    builder: (context) => GenerateQRPage(
                          url: '',
                        )));
          }
          return NavigationActionPolicy.CANCEL;
        }

        return NavigationActionPolicy.ALLOW;
      },
      onWebViewCreated: (InAppWebViewController controller) {
        webcontroller = controller;
      },
      onLoadStop: (controller, url) async {},
    );
  }
}
解决方案建议
  • 监听应用生命周期,恢复时触发WebView刷新
    你已经混入了WidgetsBindingObserver但未实现生命周期监听逻辑,添加以下代码,在应用从后台恢复时强制刷新WebView渲染:

    @override
    void initState() {
      super.initState();
      WidgetsBinding.instance.addObserver(this);
    }
    
    @override
    void dispose() {
      WidgetsBinding.instance.removeObserver(this);
      super.dispose();
    }
    
    @override
    void didChangeAppLifecycleState(AppLifecycleState state) {
      super.didChangeAppLifecycleState(state);
      if (state == AppLifecycleState.resumed) {
        // 全量刷新WebView
        webcontroller.reload();
        // 可选:若不想全量刷新,可执行JS触发页面重绘
        // webcontroller.evaluateJavascript(source: "document.body.style.display='none';document.body.style.display='block';");
      }
    }
    
  • 禁用透明背景选项
    transparentBackground: true在部分设备或场景下可能导致后台恢复时渲染层异常,尝试注释或删除该配置:

    crossPlatform: InAppWebViewOptions(
      // transparentBackground: true,
      useShouldOverrideUrlLoading: true,
      supportZoom: true,
    ),
    
  • Android端开启硬件加速
    在android/app/src/main/AndroidManifest.xml中为Activity添加硬件加速配置,解决渲染层丢失问题:

    <activity
        android:name=".MainActivity"
        android:hardwareAccelerated="true">
        <!-- 其他配置 -->
    </activity>
    
  • 通过更换Key强制WebView重建
    若上述方法无效,可在应用恢复时通过修改WebView的Key触发组件重建:

    // 在State类中添加Key变量
    Key _webViewKey = UniqueKey();
    
    @override
    void didChangeAppLifecycleState(AppLifecycleState state) {
      super.didChangeAppLifecycleState(state);
      if (state == AppLifecycleState.resumed) {
        setState(() {
          _webViewKey = UniqueKey();
        });
      }
    }
    
    // 修改InAppWebView的key引用
    InAppWebView(
      key: _webViewKey,
      // ...其他配置
    )
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 13:05:56