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
相关产品推荐
相关产品推荐

