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

Flutter/Dart插页广告仅显示一次问题求助

问题原因分析

你遇到的问题核心在于:

  • 首次广告展示后,interstitialAd被调用dispose()销毁,但没有重新加载新的广告实例,同时_isLoaded依然保持true,后续点击时尝试调用已销毁的广告对象的show()方法,导致报错。
  • onAdFailedToLoad中直接使用interstitialAd!.dispose(),如果广告从未加载成功过,会触发空指针异常。
  • 广告展示后没有触发新一轮的广告加载,无法为下一次点击准备好广告。
修复方案

下面是修改后的完整代码,关键修复点已标注:

bool _isLoaded = false;
InterstitialAd? interstitialAd;
int counter = 0;

@override
void initState() {
  super.initState();
  WidgetsBinding.instance.addObserver(this);
  _loadInterstitialAd(); // 重命名函数更清晰
}

// 统一处理广告加载逻辑,加载前先清理旧广告
void _loadInterstitialAd() {
  // 先销毁已存在的广告实例,避免内存泄漏
  if (interstitialAd != null) {
    interstitialAd!.dispose();
    interstitialAd = null;
  }
  _isLoaded = false; // 重置加载状态

  InterstitialAd.load(
    adUnitId: "ad_id",
    request: const AdRequest(),
    adLoadCallback: InterstitialAdLoadCallback(
      onAdLoaded: (ad) {
        _isLoaded = true;
        interstitialAd = ad;

        interstitialAd!.fullScreenContentCallback = FullScreenContentCallback(
          onAdDismissedFullScreenContent: (InterstitialAd ad) {
            print('ad dismissed');
            ad.dispose(); // 直接使用回调传入的ad对象,避免空指针
            _loadInterstitialAd(); // 广告关闭后立即加载新广告
          },
          onAdFailedToShowFullScreenContent: (InterstitialAd ad, AdError adError) {
            print('ad failed: ${adError.message}');
            ad.dispose(); // 使用回调传入的ad对象
            _loadInterstitialAd(); // 展示失败后也加载新广告
          },
        );
      },
      onAdFailedToLoad: (AdError error) {
        print('ad load failed: ${error.message}');
        // 这里不再调用dispose,因为广告未加载成功,interstitialAd还是null
        _loadInterstitialAd(); // 加载失败后重试(可根据需求添加重试次数限制)
      },
    ),
  );
}

void onTap() {
  if (_isLoaded && counter == 3) {
    interstitialAd!.show();
    counter = 0;
    _isLoaded = false; // 展示后立即重置加载状态,避免重复调用
  } else {
    counter++;
  }
}

@override
void dispose() {
  WidgetsBinding.instance.removeObserver(this);
  // 页面销毁时清理广告
  if (interstitialAd != null) {
    interstitialAd!.dispose();
  }
  super.dispose();
}
关键修复说明
  • 重命名showInterstitialAd为_loadInterstitialAd,明确其职责是加载广告而非展示
  • 加载新广告前先清理旧实例,避免内存泄漏
  • 广告关闭/展示失败后自动加载新广告,确保下一次点击时有可用的广告实例
  • 使用回调传入的ad对象进行销毁操作,避免空指针
  • 展示广告后立即将_isLoaded设为false,防止重复调用已展示的广告
  • 页面销毁时添加广告清理逻辑,避免内存泄漏
  • 修复onAdFailedToLoad中的空指针风险

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 09:35:23