Android集成AdMob插屏广告关闭后回显主页面1-2秒再跳转的修复
问题根因
- 核心触发原因:原代码中先调用
mInterstitialAd.show()展示广告,之后才注册AdListener,导致AdMob SDK无法及时捕获onAdClosed的回调时机,回调延迟1-2秒才触发启动逻辑,此时广告已经完全关闭、页面切回MainActivity,才会出现停留现象。 - 流程设计缺陷:原代码在广告关闭回调触发时才执行Activity启动逻辑,此时AdMob插屏广告的覆盖窗口已经完全移除,系统已经将MainActivity恢复到前台,新Activity的启动流程会排在窗口事务处理之后,进一步拉长感知延迟。
修复方案
- 调整广告监听器的注册时机
- 将
setAdListener的操作移到广告加载、展示的前置流程,确保SDK可以在广告关闭的第一时间触发回调,不要在show()调用完成后再注册监听器。
- 将
- 优化启动流程的响应速度
- 提前暂存待跳转的目标Intent,广告关闭回调触发时立即执行启动操作,减少回调内的逻辑耗时。
- 关闭页面默认的进出场动画,用
overridePendingTransition将跳转动画设为无动画,弱化用户对中间过渡页面的感知。
- 补充广告预加载逻辑
- 在每次广告关闭的回调中,立即加载下一次的插屏广告,避免后续触发跳转时因广告未加载完成导致体验断层。
- 修正Context引用方式
- 向AdsManager传入Activity实例而非全局Context,减少Activity启动时的额外Flag校验开销,同时避免内存泄漏风险。
修正后的核心代码
AdsManager 类
class AdsManager { private InterstitialAd mInterstitialAd; private Activity activityContext; private Intent pendingJumpIntent; AdsManager(Activity context) { this.activityContext = context; MobileAds.initialize(context, context.getString(R.string.adMobAppId)); mInterstitialAd = new InterstitialAd(context); mInterstitialAd.setAdUnitId(context.getString(R.string.adMobUnitId)); // 提前注册监听器,在show之前完成设置 mInterstitialAd.setAdListener(new AdListener() { @Override public void onAdClosed() { // 回调触发后立即跳转 if (pendingJumpIntent != null) { activityContext.startActivity(pendingJumpIntent); // 移除默认跳转动画,减少视觉延迟 activityContext.overridePendingTransition(0, 0); } // 预加载下一次广告 loadInterstitialAd(); } }); // 初始化时加载第一次广告 loadInterstitialAd(); } private void loadInterstitialAd() { Bundle extras = new Bundle(); extras.putBoolean("is_designed_for_families", true); AdRequest request = new AdRequest.Builder() .addNetworkExtrasBundle(AdMobAdapter.class, extras) .tagForChildDirectedTreatment(true) .build(); mInterstitialAd.loadAd(request); } void showAd(Intent targetIntent) { // 暂存跳转目标,供广告关闭时使用 pendingJumpIntent = targetIntent; if (mInterstitialAd.isLoaded()) { mInterstitialAd.show(); } else { activityContext.startActivity(targetIntent); activityContext.overridePendingTransition(0, 0); } } }
MainActivity 类
public class MainActivity extends AppCompatActivity { private AdsManager adsManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initAds(); } private void initAds() { // 传入当前Activity实例 adsManager = new AdsManager(this); } public void onClick(View view) { switch (view.getId()) { case R.id.learnButton: Intent targetIntent = new Intent(this, LearningActivity.class); if (adsManager != null) { adsManager.showAd(targetIntent); } else { startActivity(targetIntent); } break; } } }
业务适配提示
- 如果需要在LearningActivity按返回键时不回到MainActivity,可以在构造目标Intent时添加
Intent.FLAG_ACTIVITY_CLEAR_TOP标记,根据实际业务逻辑调整Activity启动模式。 - 在MainActivity的
onDestroy方法中清理AdsManager的广告引用,避免Activity销毁后广告回调持有无效引用导致崩溃。
内容的提问来源于stack exchange,提问作者Olga
相关产品推荐
相关产品推荐

