存量项目如何拥抱 KMP?从环境搭建到组件化集成的保姆级指南

摘要: Kotlin Multiplatform (KMP) 是目前我们选定的跨平台开发方案,但手头有几百万行代码的存量项目,不可能推倒重来。本文将通过"组件化集成"的思路,从零环境搭建,到处理平台差异,最后输出 AAR 和 XCFramework,实现 KMP 在大型项目中的"增量"落地。


前言:为什么是组件化集成?

KMP 的最大魅力在于它的非侵入性 。在"Brownfield(棕地/存量)"开发模式下,KMP 可以仅仅作为一个 Module(模块) 存在。

  • 对 Android 来说: 它就是一个普通的 Kotlin Library,输出 .aar
  • 对 iOS 来说: 它就是一个第三方 SDK,输出 .xcframework

这意味着:不需要重写 APP,只需要把"核心算法"、"数据层"或"新业务模块"用 KMP 写一遍,然后分发给双端使用。


第一部分:从 0 到 1 的环境准备

在开始写代码前,必须跨过环境配置这道坎。KMP 涉及双端生态,配置稍显复杂。

1. 硬件与软件清单

  • 操作系统: 推荐 macOS(必须用于编译 iOS 产物)。如果是 Windows,只能编译 Android 和 JVM 端。

  • JDK: 强烈推荐 JDK 17,兼容性最佳。

  • Android Studio: 最新稳定版。需在 SDK Manager 安装 CMakeCommand-line Tools

  • Xcode: App Store 下载最新版(仅限 Mac)。安装后务必执行:

    Bash

    csharp 复制代码
    sudo xcode-select -s /Applications/Xcode.app/Contents/Developer

2. 快速创建项目

不要手动去配置 Gradle 文件,那是噩梦的开始。请直接使用官方向导:

  1. 访问 kmp.jetbrains.com
  2. 填写 Project ID。
  3. iOS framework distribution 选择 Regular framework(适合手动集成)或 CocoaPods
  4. 下载并解压,使用 Android Studio 打开。

避坑指南: 第一次打开项目,Gradle Sync 可能会跑很久,请确保网络通畅。直到左侧 Project 视图没有红线报错,才算成功。


第二部分:架构设计与平台差异化处理

进入开发阶段,最核心的问题是:什么代码写在公用层,什么代码需要单独写?

1. 代码分层策略

KMP 项目通常包含三个核心 SourceSet:

  • commonMain (90% 代码) :业务逻辑、网络请求 (Ktor)、数据库 (SQLDelight/Room)、通用 UI (Compose Multiplatform)。
  • androidMain:Android 特有实现。
  • iosMain:iOS 特有实现。

2. 什么时候需要"单独处理"?

只要涉及**"问操作系统要权限、要硬件、要特定服务"**的场景,就需要分离。

我们使用 expect (定义接口) 和 actual (平台实现) 关键字:

场景 是否需要独立处理 解决方案
纯业务逻辑 / ViewModel ❌ 不需要 直接写在 commonMain
网络请求 / JSON 解析 ❌ 不需要 使用 Ktor + Kotlinx.serialization
相机 / 相册 / 蓝牙 ✅ 需要 common 定义接口,平台端调用 CameraX/AVFoundation
WebView / 地图 ✅ 需要 CMP 中使用 AndroidViewUIKitView 互操作
支付 SDK (微信/支付宝) ✅ 需要 封装原生 SDK 的调用接口

第三部分:核心实战------构建组件化产物

这是本文的重点。我们需要配置 build.gradle.kts,让 KMP 模块自动生成 Android 和 iOS 可以直接依赖的二进制包。

1. 配置 shared/build.gradle.kts

将以下配置应用到 KMP 模块中:

Kotlin

scss 复制代码
plugins {
    alias(libs.plugins.kotlinMultiplatform)
    alias(libs.plugins.androidLibrary)
    `maven-publish` // 用于发布 AAR
}

kotlin {
    androidTarget {
        publishLibraryVariants("release", "debug") // 允许发布 Android 变体
        compilations.all {
            kotlinOptions { jvmTarget = "1.8" }
        }
    }

    // 配置 iOS XCFramework 输出
    val iosTargets = listOf(iosX64(), iosArm64(), iosSimulatorArm64())
    iosTargets.forEach { iosTarget ->
        iosTarget.binaries.framework {
            baseName = "SharedSDK" // iOS 引用时的框架名
            isStatic = true        // 建议静态库,集成简单
        }
    }
    
    // 自动注册 XCFramework 任务
    val xcf = XCFramework("SharedSDK")
    iosTargets.forEach {
        it.binaries.framework { xcf.add(this) }
    }
    
    // ... sourceSets 配置 ...
}

// 配置 Android Maven 发布
publishing {
    publications {
        create<MavenPublication>("mavenAndroid") {
            groupId = "com.company.kmp"
            artifactId = "shared-sdk"
            version = "1.0.0"
            from(components["release"])
        }
    }
}

2. 生成产物

生成 iOS XCFramework:

在终端执行:

Bash

ruby 复制代码
./gradlew :shared:assembleSharedSDKXCFramework

产物路径: shared/build/XCFrameworks/release/SharedSDK.xcframework

生成 Android AAR:

在终端执行:

Bash

ruby 复制代码
./gradlew :shared:publishMavenAndroidPublicationToLocalRepoRepository
# 或者直接打 release 包
./gradlew :shared:assembleRelease

产物路径: shared/build/outputs/aar/shared-release.aar


第四部分:在现有 App 中集成

拿到产物后,KMP 项目的使命暂时完成,接下来是原生团队的接入工作。

Android 端接入

就像接入任何第三方库一样简单:

Kotlin

scss 复制代码
// app/build.gradle.kts
dependencies {
    // 如果发布到了 Maven 私服
    implementation("com.company.kmp:shared-sdk:1.0.0")
    // 或者直接引用本地 AAR
    implementation(files("libs/shared-release.aar"))
}

iOS 端接入

  1. 将生成的 SharedSDK.xcframework 文件夹拖入 Xcode 工程。

  2. General -> Frameworks, Libraries, and Embedded Content 中:

    • 如果是静态库 (isStatic = true):选择 Do Not Embed
    • 如果是动态库:选择 Embed & Sign
  3. 代码调用:

    Swift

    scss 复制代码
    import SharedSDK
    
    // 调用 KMP 中的逻辑
    SharedSDK.doSomething()
    
    // 如果包含 Compose UI
    let vc = MainViewController()
    self.present(vc, animated: true)

结语

通过这种**"组件化 + 二进制分发"**的模式,我们成功将 KMP 技术的引入风险降到了最低。

  • 对于原生开发人员: 不需要关心 KMP 的构建细节,只需要像使用普通 SDK 一样使用它。
  • 对于架构师: 可以在新业务中尝试 KMP,验证效率提升,而不会影响主 APP 的稳定性。

KMP 不是要取代谁,而是要成为连接 Android 和 iOS 生态的桥梁。现在,就开始增量迁移之旅吧!

相关推荐
Kapaseker7 小时前
你不看会后悔的2025年终总结
android·kotlin
alexhilton10 小时前
务实的模块化:连接模块(wiring modules)的妙用
android·kotlin·android jetpack
ji_shuke11 小时前
opencv-mobile 和 ncnn-android 环境配置
android·前端·javascript·人工智能·opencv
sunnyday042613 小时前
Spring Boot 项目中使用 Dynamic Datasource 实现多数据源管理
android·spring boot·后端
幽络源小助理14 小时前
下载安装AndroidStudio配置Gradle运行第一个kotlin程序
android·开发语言·kotlin
inBuilder低代码平台14 小时前
浅谈安卓Webview从初级到高级应用
android·java·webview
豌豆学姐14 小时前
Sora2 短剧视频创作中如何保持人物一致性?角色创建接口教程
android·java·aigc·php·音视频·uniapp
白熊小北极15 小时前
Android Jetpack Compose折叠屏感知与适配
android
HelloBan15 小时前
setHintTextColor不生效
android
洞窝技术17 小时前
从0到30+:智能家居配网协议融合的实战与思考
android