1. Kotlin Multiplatform 项目结构变革背景
2023年起,JetBrains与Google合作对Kotlin Multiplatform(KMP)的Gradle插件架构进行了重大重构。这次变革的核心是将原先分散在com.android.library和kotlin-multiplatform插件中的功能整合为专用的com.android.kotlin.multiplatform.library插件。这个新插件在AGP 8.1.0中首次亮相,并在AGP 9.0中成为官方推荐方案。
传统架构存在几个显著痛点:
- 源代码集命名混乱(如
androidAndroidTest) - 变体配置复杂度高
- 资源处理效率低下
- IDE支持不完善
新架构通过以下设计解决了这些问题:
- 单变体模型:取消buildType和productFlavor维度
- 显式API:所有配置通过
android{}DSL块完成 - 按需加载:测试、资源等特性需要显式启用
2. 新项目结构详解
2.1 目录结构规范
标准KMP模块现在采用以下目录布局:
src/ ├── androidMain/ # Android平台主代码 │ ├── kotlin/ # Kotlin源代码 │ ├── java/ # Java源代码(需显式启用) │ └── res/ # Android资源(需显式启用) ├── androidHostTest/ # 单元测试代码 ├── androidDeviceTest/ # 设备测试代码 ├── commonMain/ # 跨平台公共代码 └── iosMain/ # iOS平台代码关键变化点:
- 移除了传统的
main、test目录 - 资源必须放在平台特定目录下
- 每个sourceSet有明确的编译目标
2.2 构建配置范式
基础配置模板如下:
// build.gradle.kts plugins { alias(libs.plugins.kotlin.multiplatform) alias(libs.plugins.android.kotlin.multiplatform.library) } kotlin { android { namespace = "com.example.library" compileSdk = 34 minSdk = 23 // 显式启用Java编译 withJava() // 配置JVM目标版本 compilerOptions { jvmTarget.set(JvmTarget.JVM_11) } } sourceSets { commonMain.dependencies { implementation(kotlin("stdlib-common")) } androidMain.dependencies { implementation("androidx.core:core-ktx:1.12.0") } } }2.3 特性启用机制
新插件采用"opt-in"模式管理非核心功能:
android { // 启用Android资源处理 androidResources { enable = true } // 配置单元测试 withHostTest { isIncludeAndroidResources = true } // 配置设备测试 withDeviceTest { instrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } }3. 迁移实操指南
3.1 源代码迁移路径
从旧结构迁移需要执行以下操作:
- 将
src/main/kotlin→src/androidMain/kotlin - 将
src/test→src/androidHostTest - 将
src/androidTest→src/androidDeviceTest - 资源文件移动到
src/androidMain/res
对于非标准目录,需要通过DSL声明:
androidComponents { onVariants { variant -> variant.sources.kotlin?.addStaticSourceDirectory("custom/kotlin") variant.sources.assets?.addStaticSourceDirectory("custom/assets") } }3.2 依赖管理变革
新架构要求严格区分依赖作用域:
dependencies { // 公共依赖 "commonMainImplementation"(libs.kotlinx.coroutines.core) // Android特定依赖 "androidMainImplementation"(libs.androidx.appcompat) // 仅限开发环境的依赖 "androidRuntimeClasspath"(libs.androidx.compose.ui.tooling) }3.3 常见问题解决方案
问题1:Compose预览无法工作解决方案:确保添加预览依赖到runtimeClasspath:
dependencies { "androidRuntimeClasspath"(libs.androidx.compose.ui.tooling) }问题2:ProGuard规则失效解决方案:显式启用consumer rules发布:
android { optimization { consumerKeepRules { publish = true file("consumer-rules.pro") } } }问题3:原生代码集成对于需要C/C++代码的情况:
- 在
nativeMain中放置共享代码 - 使用KMP的
cinterop机制 - 或创建独立的Android库模块
4. 工程实践建议
4.1 多模块项目结构
推荐采用以下架构:
:shared └── build.gradle.kts (KMP模块) :androidApp └── build.gradle.kts (纯Android应用) :iosApp └── xcode.project (iOS应用)关键配置要点:
- 在settings.gradle中启用KMP插件
- 使用版本目录统一管理依赖
- 为共享模块配置发布任务
4.2 性能优化技巧
- 增量编译:确保使用KGP 2.0+的IC支持
- 缓存配置:在gradle.properties中添加:
kotlin.incremental=true kotlin.caching.enabled=true - 并行编译:设置
org.gradle.parallel=true
4.3 IDE支持方案
Android Studio最新版本已提供:
- 专用的KMP模块向导
- 多平台代码导航
- 跨平台调试支持
- Compose Multiplatform预览
对于无法升级的情况,可以:
- 安装Kotlin Multiplatform插件
- 手动配置运行配置
- 使用
./gradlew --continuous实现热重载
5. 兼容性策略
5.1 版本矩阵
确保使用以下最低版本:
| 组件 | 最低版本 | 推荐版本 |
|---|---|---|
| AGP | 8.1.0 | 9.2.0 |
| KGP | 2.0.0 | 2.0.21 |
| JDK | 11 | 17 |
5.2 渐进式迁移
对于大型项目,建议分阶段迁移:
- 先在新模块试用新插件
- 逐步迁移叶子模块
- 最后处理核心共享模块
- 使用
includeBuild维持过渡期兼容
5.3 回滚方案
如果遇到不可解决的问题:
- 备份gradle配置
- 回退到AGP 8.0.x
- 使用
androidLibrary{}DSL - 提交issue到官方追踪系统
实践提示:在迁移过程中,建议保持CI构建的监控,使用构建扫描对比性能指标,确保没有引入显著的构建时间退化。