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

AGP 9.0下Android模块中expect与actual函数的使用疑问

AGP 9.0下KMP平台actual代码实现问题解决方案

核心结论

Android模块绝非仅用于配置Application、Activity或Service,它完全可以承载Android平台特有的业务实现(包括KMP的actual代码)。你遇到的问题是AGP 9.0与Kotlin Multiplatform(KMP)插件的配置衔接问题,而非平台模块的功能限制。


解决步骤与配置要点

1. 修正模块插件与KMP目标配置

确保common模块与Android模块的插件配置正确关联:

  • Common模块(核心共享模块)的build.gradle.kts需声明KMP插件及多平台目标:
    plugins {
        id("org.jetbrains.kotlin.multiplatform")
        id("com.android.library") // 若需共享Android库能力,可选
    }
    
    kotlin {
        // 声明Android目标,关联到Android模块
        androidTarget {
            compilations.all {
                kotlinOptions.jvmTarget = "17" // 匹配项目JVM版本
            }
        }
        // 声明iOS目标
        iosX64()
        iosArm64()
        iosSimulatorArm64()
    
        sourceSets {
            val commonMain by getting
            val androidMain by getting {
                // 引入Android平台依赖(如ExoPlayer)
                dependencies {
                    implementation("com.google.android.exoplayer:exoplayer-core:2.19.1")
                    implementation("com.google.android.exoplayer:exoplayer-ui:2.19.1")
                }
            }
            val iosMain by creating {
                dependsOn(commonMain)
            }
        }
    }
    
  • Android模块(应用/库模块)的build.gradle.kts需同时应用Android与Kotlin Android插件:
    plugins {
        id("com.android.application") // 或com.android.library,依模块类型而定
        id("org.jetbrains.kotlin.android")
    }
    
    android {
        // 常规Android配置(compileSdk、defaultConfig等)
        compileSdk = 34
        defaultConfig {
            applicationId = "com.your.app"
            minSdk = 24
            targetSdk = 34
        }
        buildFeatures {
            compose = true
        }
        composeOptions {
            kotlinCompilerExtensionVersion = "1.5.11" // 匹配Kotlin版本
        }
    }
    

2. 正确放置actual代码

保持与common模块expect声明的包名一致,在Android模块的src/main/kotlin下实现actual代码:

  • Common模块的expect声明(commonMain/[包路径]/VideoPlayer.kt):
    @Composable
    expect fun VideoPlayer(url: String)
    
  • Android模块的actual实现(androidMain/[同包路径]/VideoPlayer.kt):
    import androidx.compose.foundation.layout.fillMaxSize
    import androidx.compose.runtime.DisposableEffect
    import androidx.compose.runtime.remember
    import androidx.compose.ui.Modifier
    import androidx.compose.ui.platform.LocalContext
    import com.google.android.exoplayer2.SimpleExoPlayer
    import com.google.android.exoplayer2.MediaItem
    import com.google.android.exoplayer2.ui.PlayerView
    
    @Composable
    actual fun VideoPlayer(url: String) {
        val context = LocalContext.current
        val exoPlayer = remember {
            SimpleExoPlayer.Builder(context).build().apply {
                setMediaItem(MediaItem.fromUri(url))
                prepare()
            }
        }
    
        // 释放播放器资源
        DisposableEffect(Unit) {
            onDispose { exoPlayer.release() }
        }
    
        PlayerView(
            context = context,
            modifier = Modifier.fillMaxSize(),
            player = exoPlayer
        ).apply {
            useController = true
        }
    }
    

3. 排查版本兼容性问题

AGP 9.0要求搭配Kotlin 1.9.20及以上版本,同时确保kotlinCompilerExtensionVersion(Compose相关)与Kotlin版本匹配。可在gradle.properties中确认以下配置:

kotlin.version=1.9.20
android.defaults.buildfeatures.compose=true
kotlin.mpp.enableGranularSourceSetsMetadata=true

4. Android模块的合理定位

你可以根据项目架构灵活定义Android模块的职责:

  • 若为应用启动模块:仅包含Application、Activity入口,以及应用级配置(权限、主题等)。
  • 若为平台实现模块:承载Android专属UI组件、第三方SDK封装、KMP的actual代码实现等。
    完全无需将所有平台代码强行放在common模块。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.11 16:33:23