存量项目如何拥抱 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 生态的桥梁。现在,就开始增量迁移之旅吧!

相关推荐
尤老师FPGA14 分钟前
使用ZYNQ芯片和LVGL框架实现用户高刷新UI设计系列教程(第四十五讲)
android·java·ui
北辰当尹1 小时前
xml基础
android·xml
龙之叶1 小时前
【Android Monkey源码解析四】- 异常捕获/页面控制
android·windows·adb·monkey
_F_y3 小时前
MySQL表的操作
android·数据库·mysql
yngsqq4 小时前
AndroidStudio汉化步骤
android
HyEISN5 小时前
Android 9 开启远程adb
android·adb
2501_944526425 小时前
Flutter for OpenHarmony 万能游戏库App实战 - 抽牌游戏实现
android·开发语言·python·flutter·游戏
大大祥5 小时前
穿山甲广告sdk接入
android·kotlin·音视频·视频播放器·广告sdk
2501_944526426 小时前
Flutter for OpenHarmony 万能游戏库App实战 - 笑话生成器实现
android·javascript·python·flutter·游戏
2501_944526426 小时前
Flutter for OpenHarmony 万能游戏库App实战 - 21点游戏实现
android·javascript·flutter·游戏·harmonyos