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

打开Activity时无延迟加载Interstitial Ad?加载卡顿及线程报错求助

问题解决方案

问题根源

  1. 启动延迟:原代码中triggerAd方法末尾的同步递归重试会在主线程中连续调用广告加载逻辑,直接阻塞UI初始化流程,导致Activity启动延迟。
  2. 后台加载报错: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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 18:22:53