如何在多个Activity中高效实现AdMob广告的统一接入?
多Activity统一接入AdMob横幅广告方案
有两种无需逐个配置的实现方案,优先推荐基类封装方案,适配性更强,自定义空间更高:
方案1:基类Activity封装(推荐)
实现步骤
- 第一步:抽取广告公共布局
单独创建layout/include_ad_banner.xml布局文件,统一存放广告位:
后续所有需要展示广告的Activity的布局根节点改为LinearLayout/ConstraintLayout等支持嵌套的布局,末尾加一行<?xml version="1.0" encoding="utf-8"?> <com.google.android.gms.ads.AdView xmlns:ads="http://schemas.android.com/apk/res-auto" android:id="@+id/adView" android:layout_width="match_parent" android:layout_height="wrap_content" ads:adSize="BANNER" ads:adUnitId="ca-app-pub-3940256099942544/6300978111"/><include layout="@layout/include_ad_banner"/>即可,不需要重复编写广告配置。 - 第二步:封装广告逻辑到基类Activity
创建BaseBannerAdActivity继承AppCompatActivity,把所有广告逻辑迁移到基类:
该方案同时修复了你原有代码中重复创建AdView的问题,不需要同时new AdView和通过findViewById获取实例。public class BaseBannerAdActivity extends AppCompatActivity { private AdView mAdView; // 标记当前页面是否需要展示广告,不需要的Activity可以重写该方法返回false protected boolean isNeedShowAd() { return true; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (isNeedShowAd()) { initAd(); } } private void initAd() { // 广告初始化建议移到Application的onCreate中,避免每次启动Activity都重复初始化 // MobileAds.initialize(this, initializationStatus -> {}); mAdView = findViewById(R.id.adView); AdRequest adRequest = new AdRequest.Builder().build(); mAdView.loadAd(adRequest); } // 同步AdView生命周期,避免内存泄漏 @Override protected void onPause() { if (mAdView != null) mAdView.pause(); super.onPause(); } @Override protected void onResume() { super.onResume(); if (mAdView != null) mAdView.resume(); } @Override protected void onDestroy() { if (mAdView != null) mAdView.destroy(); super.onDestroy(); } } - 第三步:所有需要展示广告的Activity继承该基类即可,例如原来的MainActivity改为:
// 仅需修改继承关系,无需重复编写广告逻辑 public class MainActivity extends BaseBannerAdActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 页面原有业务逻辑保持不变 } // 如果某个页面不需要广告,重写isNeedShowAd返回false即可 // @Override // protected boolean isNeedShowAd() { // return false; // } }
方案2:全局生命周期回调(零侵入)
如果不想修改所有Activity的继承关系,可以直接在Application类中注册全局Activity生命周期回调,自动给所有符合条件的Activity注入广告:
public class MyApp extends Application { @Override public void onCreate() { super.onCreate(); // 全局初始化AdMob MobileAds.initialize(this, initializationStatus -> {}); // 注册Activity生命周期监听 registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() { @Override public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) { // 排除不需要广告的Activity,例如启动页、登录页等 if (activity instanceof SplashActivity || activity instanceof LoginActivity) { return; } // 给Activity布局注入广告View View rootView = activity.findViewById(android.R.id.content); if (rootView instanceof ViewGroup) { AdView adView = new AdView(activity); adView.setAdSize(AdSize.BANNER); adView.setAdUnitId("ca-app-pub-3940256099942544/6300978111"); // 调整广告位置,示例为放在页面底部 ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); ((ViewGroup) rootView).addView(adView, lp); // 加载广告 AdRequest adRequest = new AdRequest.Builder().build(); adView.loadAd(adRequest); // 把AdView存到Activity的Tag中,方便后续生命周期同步 activity.setTag(adView); } } // 同步生命周期避免内存泄漏 @Override public void onActivityPaused(@NonNull Activity activity) { Object adObj = activity.getTag(); if (adObj instanceof AdView) ((AdView) adObj).pause(); } @Override public void onActivityResumed(@NonNull Activity activity) { Object adObj = activity.getTag(); if (adObj instanceof AdView) ((AdView) adObj).resume(); } @Override public void onActivityDestroyed(@NonNull Activity activity) { Object adObj = activity.getTag(); if (adObj instanceof AdView) ((AdView) adObj).destroy(); } // 其他生命周期方法空实现即可 @Override public void onActivityStarted(@NonNull Activity activity) {} @Override public void onActivityStopped(@NonNull Activity activity) {} @Override public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {} }); } }
该方案不需要修改任何现有Activity的代码,仅需要在Manifest中把Application的name指定为自定义的MyApp即可。
注意事项
- 测试阶段请使用官方提供的测试广告ID,不要用正式ID测试,避免被判定为无效流量
- 广告初始化仅需要执行一次,放到Application的onCreate里性能更好
- 如果部分页面需要调整广告位置,优先选择基类方案,自定义灵活性更高
内容的提问来源于stack exchange,提问作者user16731355
相关产品推荐
相关产品推荐

