打开Activity时无延迟加载Interstitial Ad?加载卡顿及线程报错求助
问题解决方案
问题根源
- 启动延迟:原代码中
triggerAd方法末尾的同步递归重试会在主线程中连续调用广告加载逻辑,直接阻塞UI初始化流程,导致Activity启动延迟。 - 后台加载报错:AdMob的
InterstitialAd.load和MobileAds.initialize必须在主线程调用,但加载过程本身是异步的,不需要放到子线程,只需优化重试逻辑避免阻塞。
修复后的代码
AdsManager类
public class AdsManager { private Context context; private InterstitialAd mInterstitialAd; private int adLoadRetry = 0; private static final int MAX_RETRY_COUNT = 3; // 延迟重试间隔(毫秒),避免频繁请求 private static final long RETRY_DELAY = 1000; public AdsManager(Context context) { this.context = context; // 只初始化一次MobileAds MobileAds.initialize(context, initializationStatus -> {}); triggerAd(); } private void triggerAd() { AdRequest adRequest = new AdRequest.Builder().build(); InterstitialAd.load(context, "UnitID", adRequest, new InterstitialAdLoadCallback() { @Override public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) { super.onAdFailedToLoad(loadAdError); mInterstitialAd = null; // 仅在重试次数未达上限时,延迟重试 if (adLoadRetry < MAX_RETRY_COUNT) { adLoadRetry++; new Handler(Looper.getMainLooper()).postDelayed(() -> triggerAd(), RETRY_DELAY); } } @Override public void onAdLoaded(@NonNull InterstitialAd interstitialAd) { super.onAdLoaded(interstitialAd); mInterstitialAd = interstitialAd; // 加载成功后重置重试次数 adLoadRetry = 0; } }); } public void showAd() { if (mInterstitialAd != null && context instanceof Activity) { mInterstitialAd.show((Activity) context); // 广告展示后,立即加载下一条,保证后续点击有广告可用 triggerAd(); } } }
Activity的onCreate方法
@SuppressLint("MissingInflatedId") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_emailwriter); // 初始化广告管理器,此时加载逻辑是异步的,不会阻塞UI AdsManager adsManager = new AdsManager(this); Button button = findViewById(R.id.Button); button.setOnClickListener(view -> adsManager.showAd()); }
关键优化点
- 移除同步递归:将重试逻辑放到
onAdFailedToLoad回调中,用Handler延迟执行,避免主线程被连续调用阻塞。 - MobileAds初始化仅一次:原代码每次调用
triggerAd都初始化,现在移到构造函数只执行一次,减少冗余操作。 - 广告展示后预加载:在
showAd方法中,广告展示完成后立即触发下一次加载,保证用户后续点击时有可用广告。 - 主线程安全:所有AdMob相关操作都在主线程执行,符合SDK要求,避免"Must be called on the main UI thread"错误。
内容的提问来源于stack exchange,提问作者Awos Al-Radaideh
相关产品推荐
相关产品推荐

