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

Flutter中BannerAd/WebView从后台恢复后显示空白问题求助

问题:后台恢复后BannerAd显示黑色空白页面

应用从后台恢复后,BannerAd显示黑色空白页面。已知google_mobile_ads在Flutter中基于webview_flutter包实现,WebView也存在相同的后台恢复空白问题。AdMob/WebView的点击、滚动等功能均正常,仅渲染空白,即使新建仅包含广告的工程也会复现该问题。

以下是仅包含简单BannerAd的代码,在Flutter 3.16.3、Pixel 7 Pro设备上会出现后台恢复后空白的情况:

import 'package:flutter/material.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';

void main(){
    runApp(MaterialApp(home:AD()));
}

class AD extends StatefulWidget{
    @override
    State createState()=>_AD();
}
class _AD extends State<AD>{
    BannerAd?_ADBANNER;
    final ValueNotifier<bool>_READY=ValueNotifier<bool>(false);

    @override
    void initState(){
        super.initState();
        MobileAds.instance.initialize();
        if(null==_ADBANNER)
        _ADBANNER=
        BannerAd(
            adUnitId:'ca-app-pub-3940256099942544/6300978111',
            size:AdSize.banner,
            request:AdRequest(),
            listener:BannerAdListener(
                onAdLoaded:(AD){
                    debugPrint('Ad loaded');
                    if(!_READY.value)
                    _READY.value=true;
                },
                onAdFailedToLoad:(AD,E){
                    debugPrint('Ad failed to load: $E');
                    _READY.value=false;
                    AD.dispose();
                },
            ),
        )
        ..load();
    }

    @override
    void dispose(){
        _READY.value=false;
        _ADBANNER?.dispose();
        debugPrint('Ad disposed');
        super.dispose();
    }

    @override
    Widget build(CTX){
        return
        ValueListenableBuilder<bool>(
            valueListenable:_READY,
            builder:(CTX,V,_){
                debugPrint('LISTEN');

                if(V)
                return
                Container(
                    alignment:Alignment.center,
                    color:Colors.white,
                    child:
                    AdWidget(ad:_ADBANNER!),
                );

                else
                return
                Center(child:CircularProgressIndicator());
            }
        );
    }
}

补充信息:

  • 该问题仅在Pixel 7 Pro和Mi A1真机上出现,模拟器无此问题,调试控制台无错误。
  • 同时使用BannerAd和WebView时,SliverGrid进入视口后BannerAd会出现显示错乱,重复WebView画面。

请问我的代码中遗漏了什么?


解决方案

这个问题本质是Android平台上WebView(及基于它的google_mobile_ads)在后台恢复时的渲染层异常,和你的代码逻辑本身无关,可通过以下方式修复:

  1. 监听App生命周期,前台恢复时重新加载广告
    在State类中添加App生命周期监听,当应用从后台回到前台时,销毁旧广告并重新加载,强制重建渲染层:

    @override
    void initState() {
      super.initState();
      MobileAds.instance.initialize();
      _loadBannerAd();
      // 注册生命周期监听
      WidgetsBinding.instance.addObserver(this);
    }
    
    @override
    void dispose() {
      // 移除监听
      WidgetsBinding.instance.removeObserver(this);
      _disposeBannerAd();
      super.dispose();
    }
    
    // 重写生命周期回调
    @override
    void didChangeAppLifecycleState(AppLifecycleState state) {
      super.didChangeAppLifecycleState(state);
      if (state == AppLifecycleState.resumed) {
        // 回到前台时重置广告
        _disposeBannerAd();
        _loadBannerAd();
      }
    }
    
    // 封装广告加载方法
    void _loadBannerAd() {
      _ADBANNER = BannerAd(
        adUnitId: 'ca-app-pub-3940256099942544/6300978111',
        size: AdSize.banner,
        request: AdRequest(),
        listener: BannerAdListener(
          onAdLoaded: (AD) {
            debugPrint('Ad loaded');
            _READY.value = true;
          },
          onAdFailedToLoad: (AD, E) {
            debugPrint('Ad failed to load: $E');
            _READY.value = false;
            AD.dispose();
          },
        ),
      )..load();
    }
    
    // 封装广告销毁方法
    void _disposeBannerAd() {
      _READY.value = false;
      _ADBANNER?.dispose();
      _ADBANNER = null;
      debugPrint('Ad disposed');
    }
    
  2. 解决BannerAd与WebView共存的显示错乱
    两者同屏时Android硬件加速层易冲突,可通过隔离渲染层解决:
    给AdWidget所在容器添加RepaintBoundary包裹,避免渲染层串扰:

    Container(
      alignment: Alignment.center,
      color: Colors.white,
      child: RepaintBoundary(
        child: AdWidget(ad: _ADBANNER!),
      ),
    )
    
  3. 更新依赖版本
    确保google_mobile_ads和webview_flutter使用最新稳定版,旧版本存在此类渲染bug的概率更高。

内容的提问来源于stack exchange,提问作者facebook-570128180

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 15:01:28