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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 15:36:28