AdMob激励视频广告二次/三次加载不显示及空指针异常求助
从你给出的日志来看,核心问题是广告适配器实例在第二次/第三次请求时变为null,触发了NullPointerException。这种情况在RewardedVideoAd中很常见,通常和广告实例的生命周期管理不当有关,下面是几个经过实践验证的解决办法:
全局复用RewardedVideoAd实例,避免重复初始化
很多开发者会犯的错误是每次要展示广告时都新建一个RewardedVideoAd对象,旧实例被GC回收后,适配器的引用就丢失了。建议把广告实例放在全局单例或者Application类中,只初始化一次:public class AdSingleton { private static RewardedVideoAd sRewardedAd; public static RewardedVideoAd getInstance(Context context) { if (sRewardedAd == null) { sRewardedAd = MobileAds.getRewardedVideoAdInstance(context.getApplicationContext()); setupAdListeners(); } return sRewardedAd; } private static void setupAdListeners() { sRewardedAd.setRewardedVideoAdListener(new RewardedVideoAdListener() { @Override public void onRewardedVideoAdLoaded() { // 广告加载完成,等待展示 } @Override public void onRewardedVideoAdFailedToLoad(int errorCode) { // 加载失败立即重试 sRewardedAd.loadAd("你的广告ID", new AdRequest.Builder().build()); } @Override public void onRewardedVideoAdClosed() { // 广告关闭后马上加载下一条,保证下次有广告可展示 sRewardedAd.loadAd("你的广告ID", new AdRequest.Builder().build()); } // 实现其他必要的回调方法... }); } }在广告结束后主动触发重新加载
一定要在广告关闭(onRewardedVideoAdClosed)或者展示失败(onRewardedVideoAdFailedToShow)的回调里调用loadAd,而不是等到用户要再次看广告时才去加载。这样能保证每次用户触发展示时,广告已经提前加载完成。检查中介适配器版本兼容性
日志里提到了中介相关类com.google.ads.mediation.a.h,如果你用了第三方广告中介,务必确保:- Google Play Ads SDK和所有中介适配器的版本完全匹配(比如Ads SDK用20.6.0,对应的AdMob中介适配器也要是20.6.0)
- 把所有中介库更新到最新稳定版,旧版本的适配器经常会存在空指针bug
确保所有广告操作都在主线程执行
AdMob的所有API调用(初始化、加载、展示)都必须在主线程进行,否则很容易导致实例状态异常。如果是在子线程里触发广告展示,记得用runOnUiThread包裹:runOnUiThread(() -> { RewardedVideoAd ad = AdSingleton.getInstance(this); if (ad.isLoaded()) { ad.show(); } else { // 提示用户广告正在加载,或者主动触发一次加载 ad.loadAd("你的广告ID", new AdRequest.Builder().build()); } });
另外,建议先用AdMob的测试广告ID(比如ca-app-pub-3940256099942544/5224354917)测试,排除真实广告库存不足的问题,先验证代码逻辑是否正确。
内容的提问来源于stack exchange,提问作者Pasha Oleynik

