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

Android Admob+ViewPager切换Fragment后崩溃问题求助

解决ViewPager中AdView自动刷新导致的SIGSEGV崩溃问题

这个问题我之前也碰到过,核心原因是ViewPager会预加载并保留相邻Fragment的实例,即使Fragment切换到不可见状态,AdView的自动刷新线程仍在后台运行,当它尝试访问已经和View分离的资源时,就会触发SIGSEGV崩溃。下面给你几个可行的解决方案:

1. 严格绑定AdView生命周期到Fragment的可见性

ViewPager里的Fragment即使不可见,onResume()依然会被调用,所以不能依赖常规生命周期方法来控制AdView,得用Fragment的可见性回调:

代码示例(Java)

private AdView adView;
private ViewGroup adContainer; // 你的广告容器布局

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_1, container, false);
    adContainer = view.findViewById(R.id.ad_container);
    return view;
}

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (getContext() == null) return; // 避免空指针

    if (isVisibleToUser) {
        // 当Fragment可见时,初始化并加载广告
        if (adView == null) {
            adView = new AdView(getContext());
            adView.setAdUnitId("ca-app-pub-xxx/xxx"); // 替换为你的广告ID
            adView.setAdSize(AdSize.BANNER);
            adContainer.addView(adView);
            
            AdRequest adRequest = new AdRequest.Builder().build();
            adView.loadAd(adRequest);
        } else {
            adView.resume(); // 恢复广告刷新(如果之前暂停过)
        }
    } else {
        // 当Fragment不可见时,暂停或销毁广告
        if (adView != null) {
            adView.pause();
            // 如果确定短时间内不会回到这个Fragment,可以直接销毁
            // adView.destroy();
            // adView = null;
        }
    }
}

@Override
public void onDestroyView() {
    super.onDestroyView();
    // 彻底销毁AdView,避免内存泄漏
    if (adView != null) {
        adView.destroy();
        adView = null;
    }
}

如果是使用ViewPager2,可以重写onHiddenChanged(boolean hidden)方法来替代setUserVisibleHint,逻辑完全一致。

2. 禁用AdView的自动刷新(不推荐但可行)

Admob默认每60秒自动刷新一次广告,如果你确实不需要自动刷新,可以在广告加载完成后停止刷新:

adView.setAdListener(new AdListener() {
    @Override
    public void onAdLoaded() {
        super.onAdLoaded();
        // 广告加载完成后,停止自动刷新
        adView.stopLoading();
    }
});

⚠️ 注意:禁用自动刷新会直接影响广告收益,官方不推荐这么做,除非你的业务场景确实不需要。如果之后需要手动刷新,可以再次调用adView.loadAd(adRequest)。

3. 调整ViewPager的预加载策略

ViewPager默认会预加载1个相邻Fragment,你可以尝试设置不预加载:

viewPager.setOffscreenPageLimit(0);

不过这个方法有局限性:Android 4.0+之后,系统可能会强制保留至少1个页面的实例,所以只能作为辅助手段,不能单独依赖它解决问题。


综合来看,方案1是最可靠的,通过绑定AdView的生命周期到Fragment的可见状态,从根源上避免了后台刷新导致的资源访问问题。

内容的提问来源于stack exchange,提问作者Ludo MacPhee

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 03:36:07