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
相关产品推荐
相关产品推荐

