📱 What is AdMob? A Complete Guide for App Developers
If you're an app developer looking to monetize your Android or iOS apps, Google AdMob is one of the most powerful and reliable platforms to consider. In this guide, we’ll dive into what AdMob is, how it works, its key features, integration steps (including Jetpack Compose support), best practices, and how to maximize revenue from it.
🚀 What is AdMob?
AdMob (short for Advertising on Mobile) is a mobile advertising platform by Google that allows developers to earn revenue by displaying ads inside their apps. AdMob connects app developers with advertisers via Google Ads, offering relevant, targeted, and high-quality ad experiences.
🎯 Why Choose AdMob?
- Backed by Google: Secure and trustworthy ecosystem.
- Cross-platform: Works for both Android and iOS.
- Supports Mediation: Combines multiple ad networks to increase revenue.
- Rich Analytics: Deep insights via Firebase integration.
- Flexible Ad Formats: Banner, Interstitial, Native, and Rewarded ads.
🛠️ Key Features of AdMob
1. Multiple Ad Formats
- Banner Ads: Rectangular ads at the top or bottom of the screen.
- Interstitial Ads: Full-screen ads at transitions (e.g., between levels).
- Rewarded Ads: Voluntary video ads in exchange for rewards.
- Native Ads: Seamlessly blend into your app's UI.
2. Ad Mediation
Serve ads from networks like Facebook Audience Network, Unity Ads, and more to increase fill rates and optimize eCPM.
3. Ad Targeting
AdMob uses location, device type, user interests, and demographics to show relevant ads and improve engagement.
4. Firebase Integration
Track user behavior, monitor ad performance, and run A/B tests using Firebase.
⚙️ How AdMob Works
- Developer integrates the AdMob SDK.
- App requests an ad.
- AdMob delivers the best available ad.
- Ad is displayed in the app.
- Developer earns money when users interact.
🧑💻 How to Integrate AdMob in Android (Jetpack Compose Compatible)
✅ Step 1: Create an AdMob Account
- Visit AdMob.
- Sign in and register your app.
- Copy your App ID and Ad Unit IDs.
✅ Step 2: Add Dependencies
Project-level build.gradle:
buildscript {
dependencies {
classpath 'com.google.gms:google-services:4.3.15'
}
}
App-level build.gradle:
plugins {
id 'com.android.application'
id 'com.google.gms.google-services'
}
dependencies {
implementation 'com.google.android.gms:play-services-ads:22.5.0'
}
Ensure minSdkVersion
is at least 19
.
✅ Step 3: Add AdMob App ID in AndroidManifest.xml
<manifest>
<application>
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy"/>
</application>
</manifest>
✅ Step 4: Initialize Mobile Ads SDK
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
MobileAds.initialize(this) {}
setContent {
MyApp()
}
}
✅ Step 5: Banner Ads in Jetpack Compose
@Composable
fun BannerAdView(adUnitId: String) {
AndroidView(
factory = { context ->
AdView(context).apply {
adSize = AdSize.BANNER
this.adUnitId = adUnitId
loadAd(AdRequest.Builder().build())
}
},
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
)
}
✅ Step 6: Interstitial Ads
var mInterstitialAd: InterstitialAd? = null
fun loadInterstitial(context: Context, adUnitId: String) {
val adRequest = AdRequest.Builder().build()
InterstitialAd.load(context, adUnitId, adRequest, object : InterstitialAdLoadCallback() {
override fun onAdLoaded(ad: InterstitialAd) {
mInterstitialAd = ad
}
override fun onAdFailedToLoad(adError: LoadAdError) {
mInterstitialAd = null
}
})
}
fun showInterstitial(context: Context) {
mInterstitialAd?.show(context as Activity)
}
✅ Step 7: Rewarded Ads (Optional)
var rewardedAd: RewardedAd? = null
fun loadRewardedAd(context: Context, adUnitId: String) {
RewardedAd.load(context, adUnitId, AdRequest.Builder().build(), object : RewardedAdLoadCallback() {
override fun onAdLoaded(ad: RewardedAd) {
rewardedAd = ad
}
override fun onAdFailedToLoad(adError: LoadAdError) {
rewardedAd = null
}
})
}
fun showRewardedAd(context: Context, onReward: () -> Unit) {
rewardedAd?.show(context as Activity) {
onReward()
}
}
🧠 Best Practices to Maximize AdMob Revenue
- Mix Rewarded Ads and Interstitial Ads.
- Respect UX: Avoid frequent or disruptive ads.
- Use Ad Mediation to optimize earnings.
- Integrate Firebase to monitor and adjust.
- A/B test ad placements.
- Never click your own ads – it’s against policy.
🧾 Key AdMob Terms
Term | Meaning |
---|---|
CPM | Cost per 1000 impressions |
CTR | Click-through rate |
eCPM | Effective CPM (average revenue per 1000 impressions) |
Impression | Display of an ad to a user |
Fill Rate | % of ad requests that are filled with ads |
⚠️ AdMob Policy Essentials
- Never click your own ads or encourage others.
- Don’t place ads on splash or exit screens.
- Get user consent in regions like the EU (GDPR).
- Full policy: AdMob Policy
✅ Conclusion
AdMob is a feature-rich and beginner-friendly monetization platform backed by Google. Whether you're using XML or Jetpack Compose, you can easily add banners, interstitials, and rewarded ads with some boilerplate code.
At CodingBihar.com, we always say: “Learn by doing!”
So build your app, follow this guide, and start monetizing today with AdMob!
Custom Native Ad Layout in Jetpack Compose (Compose-Only UI)
This guide shows how to render AdMob Native Ads with a fully customized layout in Jetpack Compose using NativeAd
data and Compose components.
1. Add AdMob Dependency
implementation("com.google.android.gms:play-services-ads:22.5.0")
2. Custom Composable for Native Ad Layout
@Composable
fun CustomNativeAdView(nativeAd: NativeAd) {
Column(
modifier = Modifier
.fillMaxWidth()
.background(Color.White)
.padding(12.dp)
.border(1.dp, Color.Gray, RoundedCornerShape(8.dp))
) {
Text(
text = nativeAd.headline ?: "",
style = MaterialTheme.typography.titleMedium,
color = Color.Black
)
Spacer(modifier = Modifier.height(8.dp))
nativeAd.icon?.drawable?.let { icon ->
AndroidView(
factory = { ImageView(it).apply { setImageDrawable(icon) } },
modifier = Modifier.size(60.dp)
)
}
Spacer(modifier = Modifier.height(8.dp))
Text(
text = nativeAd.body ?: "",
style = MaterialTheme.typography.bodyMedium,
color = Color.DarkGray
)
}
}
3. Load and Show Native Ad in Compose
@Composable
fun NativeAdComposeStyled(adUnitId: String) {
val context = LocalContext.current
var nativeAd by remember { mutableStateOf<NativeAd?>(null) }
DisposableEffect(Unit) {
val adLoader = AdLoader.Builder(context, adUnitId)
.forNativeAd { ad: NativeAd -> nativeAd = ad }
.build()
adLoader.loadAd(AdRequest.Builder().build())
onDispose { nativeAd?.destroy() }
}
nativeAd?.let {
CustomNativeAdView(nativeAd = it)
} ?: Box(
modifier = Modifier
.fillMaxWidth()
.height(120.dp),
contentAlignment = Alignment.Center
) {
CircularProgressIndicator()
}
}
4. Use in Your Screen
@Composable
fun AdScreen() {
NativeAdComposeStyled("ca-app-pub-3940256099942544/2247696110") // Test Ad Unit
}
⚠️ Notes
- Use test ad units during development to avoid policy violations.
- Jetpack Compose doesn't natively support NativeAdView, but this Compose-only UI approach lets you fully style ads your way.
📱 How to Handle AdMob Native Ad Lifecycle in Jetpack Compose
Managing the lifecycle of NativeAd
is critical to avoid memory leaks or crashes. Here's a clean, Compose-only way to load, display, and destroy native ads properly.
✅ Why Is Cleanup Important?
- NativeAd holds resources like images and views.
- Improper cleanup causes memory leaks and UI bugs.
- Compose lifecycle is different from View-based UI, so manual cleanup is essential.
🔹 Jetpack Compose Code with Lifecycle Handling
@Composable
fun NativeAdComposeStyled(adUnitId: String) {
val context = LocalContext.current
var nativeAd by remember { mutableStateOf<NativeAd?>(null) }
DisposableEffect(Unit) {
val adLoader = AdLoader.Builder(context, adUnitId)
.forNativeAd { ad: NativeAd -> nativeAd = ad }
.build()
adLoader.loadAd(AdRequest.Builder().build())
// CLEANUP when composable leaves the composition
onDispose {
nativeAd?.destroy()
}
}
nativeAd?.let {
CustomNativeAdView(nativeAd = it)
}
}
🧼 What Does onDispose
Do?
onDispose
inside DisposableEffect
runs when the Composable is removed from the screen. This is where you must call:
nativeAd?.destroy()
This prevents memory leaks and keeps your app stable.
🔸 Best Practices Summary
Tip | Why |
---|---|
Call nativeAd?.destroy() | Releases native ad resources |
Use remember | Stores ad instance in Composable scope |
Don’t reuse destroyed ads | Always load new ad per screen view |
Don’t keep NativeAd in ViewModel | It holds UI references—use in UI only |
🧪 Test It!
Try rotating the device or navigating away. If there's no crash or memory leak, you've handled the lifecycle properly!
💡 Final Tip
Use test Ad Unit IDs during development:
- Native Ad Test ID:
ca-app-pub-3940256099942544/2247696110
That's it! You now know how to manage native ad lifecycle in Jetpack Compose effectively.