加载Google Admob插屏广告时应用触发空指针异常崩溃求助
崩溃根本原因
你遇到的空指针异常是在调用setFullScreenContentCallback方法时,mInterstitialAd对象为null导致的,触发场景有两种:
- 插屏广告还未加载完成就触发了展示逻辑
- 插屏广告加载失败,
mInterstitialAd被赋值为null后触发了展示逻辑
你之前长期运行正常是因为之前广告加载成功率高,几乎不会出现加载未完成/加载失败就调用展示的场景,近期可能因为AdMob广告填充策略变化、Google Play服务更新、你所在区域广告填充率下降等原因,广告加载失败概率升高,就触发了崩溃。
存在的代码问题
setCallback()方法没有对mInterstitialAd做非空校验,直接调用其方法- 回调设置时机错误:FullScreenContentCallback应该在广告加载成功时立刻设置,而非等到要展示广告的时候才设置
onAdFailedToLoad回调中日志输出错误,误写为onAdLoaded,会误导问题排查
修复方案
1. 调整回调设置时机
将回调设置逻辑移到onAdLoaded回调中,广告加载成功后直接绑定回调,删除原有展示前设置回调的逻辑,修复后的代码示例如下:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); MobileAds.initialize(this, new OnInitializationCompleteListener() { @Override public void onInitializationComplete(InitializationStatus initializationStatus) { } }); loadInterstitialAd(); } // 单独封装广告加载方法,方便后续加载失败重试 private void loadInterstitialAd() { AdRequest adRequest = new AdRequest.Builder().build(); InterstitialAd.load(this,"ca-app-pub-93706071examplenumber/4141725063", adRequest, new InterstitialAdLoadCallback() { @Override public void onAdLoaded(@NonNull InterstitialAd interstitialAd) { mInterstitialAd = interstitialAd; Log.i("TAG", "onAdLoaded"); // 广告加载成功后立刻设置回调 mInterstitialAd.setFullScreenContentCallback(new FullScreenContentCallback(){ @Override public void onAdDismissedFullScreenContent() { Log.d("TAG", "The ad was dismissed."); // 广告关闭后可以预加载下一次广告 mInterstitialAd = null; loadInterstitialAd(); } @Override public void onAdFailedToShowFullScreenContent(AdError adError) { Log.d("TAG", "The ad failed to show."); mInterstitialAd = null; // 展示失败也可以重试加载 loadInterstitialAd(); } @Override public void onAdShowedFullScreenContent() { mInterstitialAd = null; Log.d("TAG", "The ad was shown."); } }); } @Override public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) { // 修正日志输出 Log.i("TAG", "onAdFailedToLoad: " + loadAdError.getMessage()); mInterstitialAd = null; // 可选:增加带退避的重试逻辑,避免频繁请求 } }); } private void showInterstitial(){ if (mInterstitialAd != null ) { mInterstitialAd.show(MainActivity.this); } else { Log.d("TAG", "The interstitial ad wasn't ready yet."); // 可选:广告未就绪时可以触发一次重新加载 loadInterstitialAd(); } }
2. 可选兼容方案
如果需要保留原有setCallback方法,必须在方法入口增加非空校验:
private void setCallback(){ if (mInterstitialAd == null) { callbackActive = false; return; } callbackActive = true; // 后续原有回调设置逻辑 }
内容的提问来源于stack exchange,提问作者OSbOoL
相关产品推荐
相关产品推荐

