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

