使用Volley获取AdMob ID后,应用加载插屏广告崩溃问题排查
AdMob插屏广告加载崩溃与重复设置ID警告的解决
问题详情
我通过Volley库从服务器获取AdMob ID,用于加载横幅/插屏广告,但每次启动插屏广告时应用都会崩溃,Logcat报错:
"The ad unit ID must be set on InterstitialAd before loadAd is called."
报错代码位于onPageStarted方法中:
@Override public void onPageStarted(WebView view, String url, Bitmap favicon) { if (!isRedirected || INCREMENT_WITH_REDIRECTS) { super.onPageStarted(view, url, favicon); webViewCount = webViewCount + 1; if (webViewCount >= ServerClass.SHOW_AD_AFTER_X) { if (ServerClass.SHOW_FULL_SCREEN_AD && !HIDE_ADS_FOR_PURCHASE) { if (ServerClass.USE_FACEBOOK_ADS) { if (facebookInterstitialAd != null) { facebookInterstitialAd.loadAd(); } } else { if (mInterstitialAd != null) { final AdRequest fullscAdRequest = new AdRequest.Builder().build(); mInterstitialAd.loadAd(fullscAdRequest); } } } } } }
修改代码后(添加setAdUnitId),又出现新警告:
"The ad unit ID can only be set once on InterstitialAd."
因为setAdUnitId已在onCreate方法中调用过:
if (!HIDE_PURCHASE) { if (ServerClass.FACEBOOK_ADS) { // 相关代码 } else { mInterstitialAd = new InterstitialAd(this); mInterstitialAd.setAdUnitId(ServerClass.interstitial_full); mInterstitialAd.setAdListener(new AdListener() { public void onAdLoaded() { showInterstitial(); } }); } }
疑问:如何避免应用崩溃?为何日志显示服务器数据已获取到,仍会出现该问题?
解决办法
1. 延迟初始化InterstitialAd到Volley回调完成后
问题核心是**onCreate初始化mInterstitialAd时,Volley可能还未完成服务器请求,导致ServerClass.interstitial_full为空或无效**。此时设置的ID是无效的,后续调用loadAd就会触发崩溃。
正确流程:先完成Volley请求获取AdID,再初始化插屏广告:
// Volley请求服务器获取AdID的成功回调 @Override public void onResponse(String response) { // 解析服务器响应,将正确的AdID赋值给ServerClass.interstitial_full ServerClass.interstitial_full = parseAdIdFromResponse(response); // 确认不需要隐藏广告且不用Facebook广告时,初始化插屏广告 if (!HIDE_PURCHASE && !ServerClass.FACEBOOK_ADS) { mInterstitialAd = new InterstitialAd(MainActivity.this); mInterstitialAd.setAdUnitId(ServerClass.interstitial_full); mInterstitialAd.setAdListener(new AdListener() { @Override public void onAdLoaded() { showInterstitial(); } @Override public void onAdClosed() { // 广告关闭后重新创建实例,支持下次加载 resetInterstitialAd(); } }); } } // 辅助方法:重置插屏广告实例 private void resetInterstitialAd() { if (!HIDE_PURCHASE && !ServerClass.FACEBOOK_ADS) { mInterstitialAd = new InterstitialAd(MainActivity.this); mInterstitialAd.setAdUnitId(ServerClass.interstitial_full); mInterstitialAd.setAdListener(mInterstitialAd.getAdListener()); } }
2. 加载前校验AdUnitID有效性
在onPageStarted中加载广告前,先确认ID已正确设置,避免重复调用setAdUnitId:
else { if (mInterstitialAd != null) { String adUnitId = mInterstitialAd.getAdUnitId(); // 校验ID非空且不是测试ID(可根据实际情况调整) if (!TextUtils.isEmpty(adUnitId) && !adUnitId.equals("ca-app-pub-3940256099942544/1033173712")) { final AdRequest fullscreenAdRequest = new AdRequest.Builder().build(); mInterstitialAd.loadAd(fullscreenAdRequest); } else { Log.e("AdIssue", "插屏广告ID无效或未设置"); } } }
3. 注意插屏广告的生命周期限制
AdMob的InterstitialAd实例只能加载一次广告,展示后必须重新创建实例才能再次加载。所以在广告关闭的回调中重新初始化实例,确保后续加载正常。
内容的提问来源于stack exchange,提问作者Choki
相关产品推荐
相关产品推荐

