AdMob Android Quickstart 实战指南:基于 AdView 与 InterstitialAd 实现横幅广告和插屏广告

发布时间:2026/10/7 20:17:02
AdMob Android Quickstart 实战指南:基于 AdView 与 InterstitialAd 实现横幅广告和插屏广告
示例工程【免费下载链接】quickstart-androidFirebase Quickstart Samples for Android项目地址https://gitcode.com/gh_mirrors/qu/quickstart-android点击查看免费下载导读本文以 quickstart-android 仓库中的 admob 示例 为主体系统讲解如何在 Android 应用中集成 Google Mobile Ads SDK通过AdRequestAdView展示横幅广告Banner Ad、通过InterstitialAd展示插屏广告Interstitial Ad的完整流程。读完本文你将掌握 AdMob 应用 ID 与广告单元 ID 的配置方法、两类广告的加载与展示调用链、广告生命周期管理以及 Java / Kotlin 双版本示例的工程结构。以下截屏为该示例应用在设备上的实际运行效果顶部为 Firebase 标识与 SHOW INTERSTITIAL AD 按钮底部即为 320×50 的 AdMob 测试横幅广告。一、示例项目要解决什么问题admob/README.md 明确指出该 quickstart 的核心目的是演示两类最常见的 AdMob 广告形式横幅广告Banner Ad通过AdRequest与AdView组合实现常驻于页面底部插屏广告Interstitial Ad通过InterstitialAd实现以全屏形式在页面切换等时机弹出。示例运行后屏幕上会直接展示一条测试横幅广告和一条测试插屏广告——这意味着整个示例在未接入真实广告单元的情况下即可跑通完整的「加载 → 展示 → 关闭 → 重新加载」链路非常适合作为接入 AdMob 的起点工程。从源码结构看项目对 Java 与 Kotlin 提供了完全对等的两份实现入口 EntryChoiceActivity.kt 在启动时让用户二选一分别跳转到 java 版 MainActivity 与 kotlin 版 MainActivity两者的页面导航逻辑Navigationnav_graph完全一致真正的广告业务代码则集中在两个版本的FirstFragment中。二、接入前的准备工作1. 添加 Firebase 到 Android 项目按官方标准流程将 Firebase 接入 Android 工程添加 google-services 插件、放置google-services.json这是后续使用 AdMob 的前提。需要特别留意的一点AdMob 广告单元 ID 并不存放在google-services.json中这一点在 FirstFragment.java 的注释中有明确说明——开发者要么将其作为自定义值存入字符串资源要么直接使用常量。2. 配置 AdMob 应用 ID关键步骤README 给出了最核心的配置操作修改src/main/res/values/strings.xml中的admob_app_id字符串替换为你自己的 AdMob 应用 ID。在仓库中对应文件为 admob/app/src/main/res/values/strings.xml!-- TODO: Replace this with your own Admob App ID! This value is only a sample. -- string nameadmob_app_idca-app-pub-3940256099942544~3347511713/stringREADME 特别强调这个 ID 会在两处被使用AndroidManifest.xml中的meta-data节点——它是 Google Mobile Ads SDK 初始化所必需的元数据缺失或配置错误会导致应用直接崩溃Manifest 注释明确写着 This metadata is required or your app will crash!meta-data android:namecom.google.android.gms.ads.APPLICATION_ID android:valuestring/admob_app_id /MainActivity / FirstFragment 中的校验逻辑Java 版 FirstFragment.java 与 Kotlin 版 FirstFragment.kt 都实现了checkIds()方法——若admob_app_id仍是内置测试 ID会输出警告日志提示开发者参考 README 修改private void checkIds() { if (TEST_APP_ID.equals(getString(R.string.admob_app_id))) { Log.w(TAG, Your admob_app_id is not configured correctly, please see the README); } }这可以看作一个配置未完成的运行时提醒机制避免开发者把测试 ID 带上生产环境而不自知。3. Manifest 中的权限与 AdActivity 声明AndroidManifest.xml 中还需要声明以下内容示例均已包含uses-permission android:nameandroid.permission.INTERNET / uses-permission android:nameandroid.permission.ACCESS_NETWORK_STATE /INTERNET广告请求依赖网络必须声明ACCESS_NETWORK_STATESDK 用于感知网络状态以决定广告请求策略。同时必须显式声明 SDK 内部的AdActivity并为其配置configChanges与透明主题否则广告展示时可能因配置变更问题出现异常activity android:namecom.google.android.gms.ads.AdActivity android:configChangeskeyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize android:themeandroid:style/Theme.Translucent /三、横幅广告Banner Ad实现1. 在布局中声明 AdView横幅广告的核心是com.google.android.gms.ads.AdView。在 fragment_first.xml 中它被直接声明为布局的一部分并通过两个自定义属性完成配置com.google.android.gms.ads.AdView android:idid/adView android:layout_widthwrap_content android:layout_heightwrap_content android:layout_alignParentBottomtrue android:layout_centerHorizontaltrue ads:adSizeBANNER ads:adUnitIdstring/banner_ad_unit_id app:layout_constraintBottom_toBottomOfparent app:layout_constraintEnd_toEndOfparent app:layout_constraintStart_toStartOfparent /ads:adSizeBANNER指定广告尺寸为标准横幅320×50 dpads:adUnitIdstring/banner_ad_unit_id指定横幅广告单元 ID。对应的广告单元 ID 同样定义在 strings.xmlstring namebanner_ad_unit_idca-app-pub-3940256099942544/6300978111/string string nameinterstitial_ad_unit_idca-app-pub-3940256099942544/1033173712/string这两个 ID 均为 Google 提供的专用测试广告单元ca-app-pub-3940256099942544前缀与测试应用 ID 配套使用保证返回的一定是测试广告不会产生真实计费。2. 初始化 SDK 并加载横幅在 FirstFragment.javaKotlin 版见 FirstFragment.kt中onViewCreated完成了三件事// Initialize the Google Mobile Ads SDK MobileAds.initialize(getContext()); mAdView binding.adView; requestNewInterstitial();MobileAds.initialize(context)SDK 初始化入口应在应用早期调用拿到binding.adView引用对应布局中的AdView调用requestNewInterstitial()该方法内同时完成横幅与插屏的加载。横幅的加载逻辑封装在同方法的开头private void requestNewInterstitial() { AdRequest adRequest new AdRequest.Builder().build(); mAdView.loadAd(adRequest); ... }调用链非常清晰AdRequest.Builder().build()构造一个空的无定向参数的广告请求对象随后AdView.loadAd(adRequest)异步发起横幅广告请求。从源码结构看示例刻意保持了最简单的请求构造方式便于开发者先跑通全链路再按业务需要为AdRequest.Builder()追加年龄、性别、关键词等定向参数。四、插屏广告Interstitial Ad实现1. 异步加载与回调插屏广告与横幅的关键区别在于插屏是一个独立的全屏对象需要先异步加载、再在合适的时机手动展示。示例在requestNewInterstitial()中完成加载见 FirstFragment.javaInterstitialAd.load(getContext(), getString(R.string.interstitial_ad_unit_id), adRequest, new InterstitialAdLoadCallback() { Override public void onAdLoaded(NonNull InterstitialAd interstitialAd) { super.onAdLoaded(interstitialAd); mInterstitialAd interstitialAd; // Ad received, ready to display if (mLoadInterstitialButton ! null) { mLoadInterstitialButton.setEnabled(true); } ... } Override public void onAdFailedToLoad(NonNull LoadAdError loadAdError) { super.onAdFailedToLoad(loadAdError); mInterstitialAd null; Log.w(TAG, onAdFailedToLoad: loadAdError.getMessage()); } });值得学习的工程实践onAdLoaded将加载成功的InterstitialAd实例暂存同时启用显示插屏按钮——按钮初始是禁用的mLoadInterstitialButton.setEnabled(mInterstitialAd ! null)只有广告真正就绪用户才能点击避免空白插屏onAdFailedToLoad将实例置空并记录LoadAdError的报错信息便于排查填充失败原因如网络问题、广告单元配置错误、政策违规等。2. 展示插屏与关闭后处理按钮点击时判断广告是否可用FirstFragment.javamLoadInterstitialButton.setOnClickListener(new View.OnClickListener() { Override public void onClick(View v) { if (mInterstitialAd ! null) { mInterstitialAd.show(getActivity()); } else { beginSecondActivity(); } } });即广告已加载 → 全屏展示插屏未加载 → 直接跳过广告跳转下一页面。这种优雅降级策略保证用户操作永远有响应。展示期间通过FullScreenContentCallback感知全屏内容的生命周期FirstFragment.javamInterstitialAd.setFullScreenContentCallback(new FullScreenContentCallback() { Override public void onAdDismissedFullScreenContent() { super.onAdDismissedFullScreenContent(); requestNewInterstitial(); // 立即预加载下一条插屏 beginSecondActivity(); // 继续原本的页面跳转 } });这里体现了一个关键最佳实践插屏广告是一次性资源展示并关闭后即失效。因此在onAdDismissedFullScreenContent用户关闭插屏回调中示例同时做了两件事调用requestNewInterstitial()为下一次展示预加载新广告并调用beginSecondActivity()继续被插屏打断的导航流程通过 Navigation 组件跳转到SecondFragment。Kotlin 版在 FirstFragment.kt 中的写法完全对应。3. 生命周期兜底onResume 重新加载在 FirstFragment.java 的onResume中还有一层保障Override public void onResume() { super.onResume(); if (mAdView ! null) { mAdView.resume(); } if (mInterstitialAd null) { requestNewInterstitial(); } }当mInterstitialAd为空例如加载失败、已展示完毕时页面恢复可见即自动发起重新加载确保插屏随时可用。五、广告生命周期管理与内存释放横幅广告AdView与 Activity/Fragment 的生命周期强相关示例在三个回调点做了对称处理Java 版见 FirstFragment.javaKotlin 版见 FirstFragment.kt生命周期回调必须执行的操作作用onPause()adView.pause()暂停广告刷新节省资源onResume()adView.resume()恢复广告刷新onDestroy()adView.destroy()释放广告资源防止内存泄漏Override public void onPause() { if (mAdView ! null) { mAdView.pause(); } super.onPause(); } Override public void onDestroy() { if (mAdView ! null) { mAdView.destroy(); } super.onDestroy(); }这是 AdMob 接入中极易被遗漏但官方强制的规范不随生命周期正确暂停/恢复/销毁AdView轻则浪费流量与电量重则引发内存问题。Kotlin 版额外在onDestroyView中将_binding置空以解除 ViewBinding 引用属于 Kotlin 侧的配套清理。六、运行验证与预期结果完成配置后在 Android 设备或模拟器上运行仓库提供gradlew与gradlew.batsettings.gradle.kts已通过include(:internal:lintchecks)等声明依赖仓库内置的 lint 检查模块。运行后即可看到 README 所述的预期结果测试横幅广告页面底部显示 320×50 的 AdMob 测试横幅文案为 Nice job! Youre displaying a 320 x 50 test ad from AdMob.测试插屏广告点击 SHOW INTERSTITIAL AD 按钮后全屏展示测试插屏关闭后自动导航到第二页面并同步预加载下一条插屏。若在onAdFailedToLoad的日志中看到失败原因可优先核对应用 ID 是否已替换、网络是否可用、广告单元 ID 格式是否正确。七、注意事项与最佳实践小结测试 ID 与生产 ID 分离示例内置的ca-app-pub-3940256099942544系列 ID 仅用于测试且不可用于其他用途上线前必须替换为 AdMob 后台创建的真实应用 ID 与广告单元 ID并移除checkIds()的测试 ID 告警路径。插屏预加载 用完即弃插屏广告应提前加载、展示一次即失效、关闭后立即重新加载示例的requestNewInterstitial()复用设计就是这一模式的范本。广告与用户流程解耦示例在广告未就绪时直接放行用户操作跳过插屏继续导航避免广告加载阻塞业务这是插屏接入的通用兜底策略。严格跟随生命周期AdView的pause() / resume() / destroy()必须与 Fragment/Activity 生命周期对齐Manifest 中的AdActivity与APPLICATION_ID元数据也缺一不可。八、进一步探索仓库想继续深入可在仓库中对照阅读以下文件Java 版广告实现FirstFragment.java、MainActivity.javaKotlin 版广告实现FirstFragment.kt、MainActivity.kt资源配置与导航strings.xml、fragment_first.xml、nav_graph_kotlin.xml构建入口settings.gradle.kts、gradle.properties这些文件共同构成了一个配置 → 加载 → 展示 → 生命周期管理完整的 AdMob 接入参考实现可直接作为业务项目中横幅与插屏广告集成的蓝本。赞分享示例工程【免费下载链接】quickstart-androidFirebase Quickstart Samples for Android项目地址https://gitcode.com/gh_mirrors/qu/quickstart-android点击查看免费下载相关推荐开源中国社区Android客户端10分钟快速上手指南开源中国社区Android客户端10分钟快速上手指南 开源中国社区Android客户端是一款专为开源爱好者打造的移动应用让你随时随地参与开源社区讨论、获取最移动开发社交猫抓资源嗅探扩展从打开页面到拿到文件猫抓资源嗅探扩展从打开页面到拿到文件 打开某个课程页右键菜单里只有复制下载按钮根本不存在。想保存那个 MP4只能打开 Network 面板一条条翻请音视频Upstash Ratelimit 最佳配置指南如何根据业务需求调整限流参数Upstash Ratelimit 最佳配置指南如何根据业务需求调整限流参数 Upstash Ratelimit 是一款专为无服务器运行时设计的限流库能够帮创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考