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
相关产品推荐
相关产品推荐

