Android Fragment中适配新版Google Ads SDK加载展示插屏广告
Android Fragment 适配 Google Ads SDK 20.x 插屏广告实现方案
新版20.x版本AdMob SDK的插屏广告API完全可以在Fragment中独立实现,不需要把逻辑迁移到宿主Activity,核心是适配新版API的一次性实例规则,替换旧版可复用InterstitialAd对象的写法即可,你原来的开关控制、频次计数、广告关闭自动预加载逻辑都可以完整保留。
核心差异说明
- 新版
InterstitialAd是一次性消费实例,单次show()之后就会失效,必须重新调用静态load方法请求新实例,不能像旧版那样对同一个对象反复调用loadAd() - 加载、展示方法需要传入Context,在Fragment中直接用
requireContext()/requireActivity()即可,只要保证调用时Fragment已经附着到Activity就不会报错 - 新增全屏内容回调替代旧版的AdListener,处理广告关闭、展示失败的逻辑
具体实现步骤
1. 定义Fragment成员变量
先在你的Fragment类里声明需要的变量,和你旧版逻辑对齐:
// 插屏广告实例 private InterstitialAd interstitialAd; // 广告展示频次计数器,复用你原来的计数逻辑 private int adCounter = 1; // 标记广告未加载完成时,是否有待执行的播放动作 private boolean pendingPlayAction = false;
2. 实现广告加载方法
直接替换你原来的loadInterstitialAd()方法,保留GDPR合规请求、开关判断逻辑:
@SuppressLint("MissingPermission") private void loadInterstitialAd() { // 总开关关闭直接退出 if (!Config.ENABLE_ADMOB_INTERSTITIAL_ON_PLAY) { Log.d("AD_LOG", "AdMob插屏广告已被配置关闭"); return; } // 已有加载完成/加载中的广告,不要重复请求 if (interstitialAd != null) return; // 复用你原来的GDPR合规广告请求构造逻辑 AdRequest adRequest = GDPR.getAdRequest(requireContext()); InterstitialAd.load( requireContext(), getString(R.string.admob_interstitial_unit_id), adRequest, new InterstitialAdLoadCallback() { @Override public void onAdLoaded(@NonNull InterstitialAd loadedAd) { interstitialAd = loadedAd; Log.d("AD_LOG", "插屏广告加载成功"); // 设置广告全屏展示回调 interstitialAd.setFullScreenContentCallback(new FullScreenContentCallback() { @Override public void onAdDismissedFullScreenContent() { // 广告正常关闭:清空实例、自动预加载下一条、执行待触发的播放逻辑 interstitialAd = null; loadInterstitialAd(); if (pendingPlayAction) { pendingPlayAction = false; startAudioPlay(); } } @Override public void onAdFailedToShowFullScreenContent(@NonNull AdError adError) { // 广告展示失败:清空实例、自动重加载、直接走播放逻辑不要卡用户 interstitialAd = null; loadInterstitialAd(); Log.e("AD_LOG", "插屏广告展示失败:" + adError.getMessage()); if (pendingPlayAction) { pendingPlayAction = false; startAudioPlay(); } } @Override public void onAdShowedFullScreenContent() { // 广告成功展示,重置频次计数器 adCounter = 1; } }); // 如果是用户点击触发的加载,加载完直接展示 if (pendingPlayAction) { showInterstitialAd(); } } @Override public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) { interstitialAd = null; Log.e("AD_LOG", "插屏广告加载失败:" + loadAdError.getMessage()); // 加载失败不要卡用户,直接执行播放逻辑 if (pendingPlayAction) { pendingPlayAction = false; startAudioPlay(); } } } ); }
3. 实现广告展示逻辑
替换你原来的showInterstitialAd()方法,保留间隔展示逻辑:
private void showInterstitialAd() { // 广告开关关闭,直接播放 if (!Config.ENABLE_ADMOB_INTERSTITIAL_ON_PLAY) { startAudioPlay(); return; } // 未到设定的展示间隔,直接计数+1后播放 if (adCounter < Config.ADMOB_INTERSTITIAL_ON_PLAY_INTERVAL) { adCounter++; startAudioPlay(); return; } // 广告已加载完成,直接展示 if (interstitialAd != null) { interstitialAd.show(requireActivity()); return; } // 广告还没加载好,标记待执行播放,触发加载,加载完成后会自动展示/播放 pendingPlayAction = true; loadInterstitialAd(); }
4. 对接业务逻辑
- 在Fragment的
onViewCreated生命周期里先调用一次loadInterstitialAd()做预加载,不要等用户点击播放才开始加载,减少等待 - 播放按钮的点击事件直接调用
showInterstitialAd()即可 - 把你原来的音频播放逻辑抽成独立的
startAudioPlay()方法,广告关闭、不需要展示广告时会自动调用:
// 播放按钮点击示例 binding.btnPlay.setOnClickListener(v -> showInterstitialAd()); // 你的原有音频播放业务逻辑 private void startAudioPlay() { // 这里写原来的音频初始化、播放、页面跳转等逻辑 }
注意事项
- 不要在Fragment未附着到Activity时(比如onCreateView之前)调用requireContext/requireActivity,会抛出异常
- 广告实例在关闭、展示失败、加载失败时必须置空,SDK不支持同一个InterstitialAd实例多次调用show(),否则会触发崩溃
- 测试阶段请使用官方测试广告ID,不要用正式广告ID刷测试流量,避免账号被限制
- Fragment销毁时可以把interstitialAd置空,避免不必要的内存泄漏
内容的提问来源于stack exchange,提问作者Radio Barcelona
相关产品推荐
相关产品推荐

