KMP 架构大升级:告别插件冲突,拥抱 AGP 9.0+ 新标准
KMP 架构大升级:告别插件冲突,拥抱 AGP 9.0+ 新标准
这是一篇关于 Kotlin Multiplatform (KMP) 项目结构从旧版本迁移到 AGP 9.0+ 兼容新架构的技术指南。
1. 背景:为什么要迁移?
在传统的 Kotlin Multiplatform (KMP) 项目(特别是使用 Compose Multiplatform 模板创建的项目)中,通常会将 com.android.application 插件直接应用在 composeApp 模块内。这种“全能模块”结构在早期非常流行,因为它简单直观。
然而,随着 Android Gradle Plugin (AGP) 的演进,尤其是在 AGP 9.0.0 之后,org.jetbrains.kotlin.multiplatform 插件与 com.android.application 插件在同一个模块内的兼容性被正式废弃(Deprecated)。
主要原因包括:
-
• 职责分离: KMP 插件旨在处理多平台共享逻辑,而 com.android.application专注于 Android 最终产物的构建,两者在 Gradle 生命周期中存在越来越多的重叠和冲突。 -
• 构建优化: 分离后,Gradle 能够更清晰地并行处理共享库编译与平台特定的应用打包。 -
• 跨平台一致性: 这种结构让 Android 端的地位与其他平台(如 iOS、Desktop)对等——都作为一个“壳工程”引用共享的 composeApp库。
2. 迁移后的效益
-
• 消除警告与错误: 完美适配 AGP 9.0+,避免未来的编译中断。 -
• 结构清晰: composeApp纯粹作为 UI 逻辑库,androidApp纯粹作为 Android 入口,逻辑边界分明。 -
• 更灵活的依赖管理: 可以在 androidApp中添加仅 Android 端的库(如 Firebase Cloud Messaging),而不会污染共享模块。 -
• 更好的预览支持: 减少了 KMP 插件对 Android Layout Inspector 等工具的干扰。
3. 迁移升级步骤
第一步:创建 androidApp 壳模块
-
1. 在根目录下新建 androidApp文件夹。 -
2. 在 settings.gradle.kts中添加include(":androidApp")。 -
3. 创建 androidApp/build.gradle.kts,应用com.android.application插件,并添加对:composeApp的依赖。
第二步:搬家(代码与资源移动)
-
1. 将 MainActivity.kt从composeApp/src/androidMain移动到androidApp/src/androidMain(或main)。 -
2. 将 AndroidManifest.xml从composeApp/src/androidMain移动到androidApp/src/androidMain。 -
3. 将所有 Android 资源文件( res/目录,如图标、字符串等)从composeApp/src/androidMain移动到androidApp/src/androidMain/res。
第三步:改造 composeApp 为 KMP 库
-
1. 修改 composeApp/build.gradle.kts: -
• 将 com.android.application替换为com.android.kotlin.multiplatform.library。 -
• 移除 defaultConfig.applicationId。 -
• 将 android { ... }块移入kotlin { android { ... } }中(针对新版 KMP 插件)。 -
2. 清理不再需要的 Android 专属依赖,将其移至 androidApp模块。
4. 新旧结构差异对照
|
|
|
|
|---|---|---|
| Android 插件 | com.android.application
composeApp |
com.android.application
androidApp |
| KMP 库插件 |
|
com.android.kotlin.multiplatform.library |
| 入口 Activity | composeApp/src/androidMain |
androidApp/src/androidMain |
| 资源文件 |
composeApp |
androidApp,共享 UI 资源在 composeApp |
| AGP 9.0 兼容性 |
|
|
5. 详细迁移核对清单 (Checklist)
用于其他项目迁移时逐项对照:
-
•版本定义 (version catalog): 在 libs.versions.toml中定义androidKotlinMultiplatformLibrary = { id = "com.android.kotlin.multiplatform.library", version.ref = "agp" }。 -
•根目录配置: 在根 build.gradle.kts的plugins块中添加该插件并设置apply false。 -
•模块依赖: androidApp的dependencies必须包含implementation(project(":composeApp"))。 -
•命名空间: 检查 androidApp的namespace是否正确(通常为xxx.xxx.xxx),composeApp的namespace建议改为xxx.xxx.xxx.compose以免冲突。 -
•源集路径: 新结构推荐 Android 源码路径为 src/androidMain/kotlin而非传统的src/main/kotlin(在 KMP 上下文中)。 -
•资源引用: 确保 MainActivity中引用的R类包名已根据androidApp的namespace更新。
6. AI 迁移指令 (Prompt)
你可以将以下这段英文 Prompt 输入给 Gemini, Claude Code 或 GitHub Copilot,以快速对其他项目执行此类自动化迁移:
Prompt:
“Refactor this KMP project to comply with the new architecture required by AGP 9.0+.
1. Create a new Android Application module named ‘androidApp’. 2. Move the com.android.applicationplugin,applicationId, and Android-specific configurations (likebuildTypes) fromcomposeApp/build.gradle.ktsto the newandroidApp/build.gradle.kts.3. Move MainActivity.kt,AndroidManifest.xml, and theresdirectory fromcomposeApp/src/androidMaintoandroidApp/src/androidMain.4. In composeApp/build.gradle.kts, replace thecom.android.applicationplugin withcom.android.kotlin.multiplatform.library. Ensure theandroidblock is moved inside thekotlinblock askotlin { android { ... } }.5. Add :androidApptosettings.gradle.ktsand make it depend on:composeApp.6. Update all package names and imports to ensure the project compiles across all targets (Android, JVM, iOS, Wasm).”
夜雨聆风