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

相关推荐
技术摆渡人2 小时前
Android 系统技术探索(3)光影魔术(SurfaceFlinger & 图形栈)。
android
某空m3 小时前
【Android】浅析DataBinding
android·开发语言
sky北城4 小时前
You are not able to choose some of the languages, because locales for them a
android
儿歌八万首4 小时前
Jetpack Compose 实战:打造高性能轮播图 (Carousel) 组件
android·前端·kotlin
QING6185 小时前
Kotlin Flow 防抖(Debounce)详解
android·kotlin·android jetpack
QING6185 小时前
Kotlin Flow 防抖(Debounce)、节流(Throttle)、去重(distinctUntilChanged) —— 新手指南
android·kotlin·android jetpack
AI视觉网奇5 小时前
android yolo12 android 实战笔记
android·笔记·yolo
海上飞猪5 小时前
【Mysql】Mysql的安装部署和使用
android·mysql·adb
我是好小孩6 小时前
【Android】项目的组件化搭建
android