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

关于KMM兼容广告服务(如Google Admob)的技术咨询

适配KMM的广告服务方案及独立实现思路

一、有没有适配KMM的Google Admob相关库?

目前社区有部分针对KMM的广告适配库,但成熟度和官方支持度远不如原生SDK。比如一些开发者维护的admob-kmp类库,能提供基础的跨平台Admob调用能力,但可能存在功能不全、版本更新滞后的问题,使用前需要结合项目需求评估库的维护状态。如果追求稳定性,官方暂时没有推出正式的KMM版Admob SDK,优先考虑原生实现方案更稳妥。

二、双平台独立实现(UI在common模块)的思路

核心是利用KMM的expect/actual机制,结合Compose Multiplatform的平台原生视图嵌入能力,把广告的加载、渲染逻辑下沉到平台模块,common模块只负责定义抽象接口和UI容器。

步骤1:Common层定义接口与UI容器

在common模块中,先定义广告管理的抽象接口,以及Compose广告容器组件:

// common/src/commonMain/kotlin/com/yourproject/ad/AdManager.kt
expect class AdManager {
    fun loadBannerAd(unitId: String)
    val adState: StateFlow<AdState>
}

sealed class AdState {
    object Loading : AdState()
    data class Loaded(val adContent: Any?) : AdState() // 存储平台原生广告实例
    data class Failed(val error: String) : AdState()
}

// common/src/commonMain/kotlin/com/yourproject/ui/AdCompose.kt
@Composable
fun BannerAd(unitId: String, adManager: AdManager) {
    val adState by adManager.adState.collectAsStateWithLifecycle()

    when (adState) {
        AdState.Loading -> {
            Box(modifier = Modifier.fillMaxWidth().height(50.dp).background(Color.Gray)) {
                Text(text = "广告加载中...", modifier = Modifier.align(Alignment.Center))
            }
        }
        is AdState.Failed -> {
            Box(modifier = Modifier.fillMaxWidth().height(50.dp).background(Color.Red)) {
                Text(text = "广告加载失败", modifier = Modifier.align(Alignment.Center))
            }
        }
        is AdState.Loaded -> {
            // 由平台层实现具体的广告视图渲染
            PlatformBannerAd(adState.adContent)
        }
    }
}

expect @Composable fun PlatformBannerAd(adContent: Any?)

步骤2:Android平台实现

在Android模块中,实现actual类,用原生Admob SDK加载广告,并通过AndroidView嵌入Compose:

// android/src/androidMain/kotlin/com/yourproject/ad/AdManagerAndroid.kt
actual class AdManager actual constructor() {
    private val _adState = MutableStateFlow<AdState>(AdState.Loading)
    actual val adState: StateFlow<AdState> = _adState

    actual fun loadBannerAd(unitId: String) {
        val adView = AdView(ApplicationProvider.getApplicationContext())
        adView.adUnitId = unitId
        adView.adSize = AdSize.BANNER

        adView.adListener = object : AdListener() {
            override fun onAdLoaded() {
                _adState.value = AdState.Loaded(adView)
            }

            override fun onAdFailedToLoad(error: LoadAdError) {
                _adState.value = AdState.Failed(error.message)
            }
        }

        adView.loadAd(AdRequest.Builder().build())
    }
}

// android/src/androidMain/kotlin/com/yourproject/ui/AdComposeAndroid.kt
actual @Composable fun PlatformBannerAd(adContent: Any?) {
    AndroidView(
        factory = { adContent as AdView },
        modifier = Modifier.fillMaxWidth()
    )
}

步骤3:iOS平台实现

在iOS模块中,用原生Admob SDK实现actual类,通过UIKitView嵌入Compose:

// ios/src/iosMain/kotlin/com/yourproject/ad/AdManagerIos.kt
actual class AdManager actual constructor() {
    private val _adState = MutableStateFlow<AdState>(AdState.Loading)
    actual val adState: StateFlow<AdState> = _adState

    actual fun loadBannerAd(unitId: String) {
        val bannerView = GADBannerView(adSize = GADAdSizeBanner)
        bannerView.adUnitID = unitId
        bannerView.rootViewController = UIApplication.shared.keyWindow?.rootViewController

        bannerView.adDelegate = object : GADBannerViewDelegateProtocol {
            override fun adViewDidReceiveAd(bannerView: GADBannerView) {
                _adState.value = AdState.Loaded(bannerView)
            }

            override fun adView(bannerView: GADBannerView, didFailToReceiveAdWithError error: GADRequestError) {
                _adState.value = AdState.Failed(error.localizedDescription)
            }
        }

        bannerView.load(GADRequest())
    }
}

// ios/src/iosMain/kotlin/com/yourproject/ui/AdComposeIos.kt
actual @Composable fun PlatformBannerAd(adContent: Any?) {
    UIKitView(
        factory = { adContent as GADBannerView },
        modifier = Modifier.fillMaxWidth()
    )
}

步骤4:在Common UI中使用

在common模块的任意Compose页面中,注入平台实现的AdManager即可调用广告组件:

@Composable
fun HomeScreen(adManager: AdManager) {
    Column {
        // 其他页面内容
        BannerAd(unitId = "your_ad_unit_id", adManager = adManager)
    }
}

额外注意事项

  • 依赖注入:可以用Koin等跨平台DI框架,在平台模块中提供AdManager实例,common模块直接注入使用。
  • 权限配置:Android需在AndroidManifest.xml中添加Admob所需权限,iOS需在Info.plist中配置广告相关权限和说明。
  • 生命周期管理:确保广告视图的生命周期与Compose页面同步,避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 22:47:37