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

如何为Firebase/Admob插屏广告实现iOS同款isReady判定?

实现类似iOS Admob isReady的安卓广告就绪判断机制

我明白你的困扰——Admob C++ SDK在安卓端没有直接对应iOS的isReady字段,靠LoadAdLastResult()确实没法准确跟踪广告是否还处于可展示状态(毕竟广告展示后这个结果还是会保留成功加载的状态)。不过我们可以通过自己维护广告生命周期状态来实现完全等效的isReady逻辑,具体步骤如下:


核心思路

手动维护一个布尔变量,通过Admob的广告回调事件来更新这个变量的状态:

  • 广告成功加载完成 → 标记为true(可展示)
  • 广告被展示/关闭/展示失败 → 标记为false(需要重新加载)

具体实现步骤

1. 定义状态变量和监听类

首先在你的游戏类中声明一个布尔变量,用来标记插屏广告的就绪状态;同时创建一个自定义的监听类,继承Admob的插屏广告监听器,用来处理广告的各种生命周期事件:

#include "firebase/admob.h"
#include "firebase/admob/interstitial_ad.h"

// 自定义插屏广告监听器,用来更新就绪状态
class InterstitialAdListener : public firebase::admob::InterstitialAd::Listener {
public:
    bool* adReadyStatus;

    // 构造函数传入状态变量的指针
    explicit InterstitialAdListener(bool* statusPtr) : adReadyStatus(statusPtr) {}

    // 广告成功加载完成时触发
    void OnAdLoaded() override {
        *adReadyStatus = true;
        CCLOG("插屏广告加载完成,就绪状态更新为true");
    }

    // 广告加载失败时触发
    void OnAdFailedToLoad(const firebase::admob::AdError& error) override {
        *adReadyStatus = false;
        CCLOG("插屏广告加载失败: 错误码%d, 信息:%s", error.code(), error.message());
    }

    // 广告被关闭时触发
    void OnAdClosed() override {
        *adReadyStatus = false;
        CCLOG("插屏广告已关闭,就绪状态重置为false");
        // 可选:这里可以立即发起下一次广告加载,提前准备好下一个广告
        // if (interstitialAd != nullptr) {
        //     firebase::admob::AdRequest request;
        //     interstitialAd->LoadAd(request);
        // }
    }

    // 广告展示失败时触发
    void OnAdFailedToShow(const firebase::admob::AdError& error) override {
        *adReadyStatus = false;
        CCLOG("插屏广告展示失败: 错误码%d, 信息:%s", error.code(), error.message());
    }
};

// 在你的游戏类成员变量中添加:
bool isInterstitialReady = false;
firebase::admob::InterstitialAd* interstitialAd = nullptr;
InterstitialAdListener* adListener = nullptr;

2. 初始化广告并绑定监听器

在游戏初始化阶段,创建插屏广告实例,绑定自定义监听器,然后发起第一次广告加载:

void initAdmobInterstitial() {
    // 替换成你的安卓插屏广告单元ID
    const char* adUnitId = "ca-app-pub-xxx/xxx";
    
    interstitialAd = new firebase::admob::InterstitialAd();
    adListener = new InterstitialAdListener(&isInterstitialReady);
    interstitialAd->SetListener(adListener);
    
    // 初始化广告
    interstitialAd->Initialize(adUnitId);
    
    // 发起第一次广告加载
    firebase::admob::AdRequest adRequest;
    interstitialAd->LoadAd(adRequest);
}

3. 使用自定义的isReady逻辑判断广告状态

当你想要展示插屏广告时,直接检查我们维护的isInterstitialReady变量即可,逻辑和iOS的isReady完全一致:

void tryShowInterstitialAd() {
    if (interstitialAd == nullptr) return;

    if (isInterstitialReady) {
        // 广告就绪,直接展示
        interstitialAd->Show();
    } else {
        // 广告未就绪,发起新的加载请求
        CCLOG("广告未就绪,开始加载新广告");
        firebase::admob::AdRequest adRequest;
        interstitialAd->LoadAd(adRequest);
    }
}

关键细节说明

  • 线程安全:Admob的回调事件是在后台线程触发的,不过我们这里只是更新布尔变量,不需要操作UI,所以无需额外处理线程切换;如果需要在回调中触发Cocos2d-x的UI操作,记得用Director::getInstance()->getScheduler()->performFunctionInCocosThread()切换到主线程。
  • 资源释放:在游戏退出或不再需要广告时,记得释放广告实例和监听器:
    if (interstitialAd != nullptr) {
        interstitialAd->Destroy();
        delete interstitialAd;
        interstitialAd = nullptr;
    }
    if (adListener != nullptr) {
        delete adListener;
        adListener = nullptr;
    }
    
  • 提前预加载:如果想让广告随时能展示,可以在广告关闭后立即发起下一次加载(就是上面回调中注释的代码),这样用户下次触发广告时就能直接展示,提升体验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:33:12