找回密码
 立即注册
首页 业界区 业界 跨平台之 KMP / KMM 详解

跨平台之 KMP / KMM 详解

屠焘 4 天前
任何事情,急于求成都是幼稚的幻想,急于求成的结果一定是不成,对此不应该有任何怀疑。
一. KMP 和 Compose Multiplatform

摘要:减少为不同平台编写和维护相同业务逻辑代码所花费的时间,同时又能保留 NA 编程的录活性和优势。
在移动应用开发领域,Kotlin Multiplatform Mobile (KMM) 和 Compose Multiplatform 的结合正在成为一种强大的解决方案。它们不仅解决了传统跨平台开发中的诸多痛点,还提供了许多独特的优势,使得开发者能够更加高效地构建和维护跨平台应用。以下是它的主要优势:

  • 代码复用
    KMM 和 Compose Multiplatform 允许开发者在 Android 和 iOS 之间共享大部分代码,包括业务逻辑和 UI 组件。
  • 性能优化
    与某些其他跨平台框架不同,KMM 生成的代码是直接运行在目标平台的原生环境中的。这意味着开发者可以享受到与原生开发相同的性能和系统级优化。
  • 平台特性和灵活性
    KMM 通过 expect 和 actual 关键字,允许开发者为不同的平台编写特定的实现。这种灵活性使得开发者可以充分利用各个平台的特性,而不会妥协于跨平台的限制。Compose Multiplatform 同样支持这种灵活性,确保 UI 设计可以根据平台的需求进行优化。
  • 一致的开发体验
    Kotlin 作为一种现代语言,拥有简洁的语法和强大的功能特性,深受开发者喜爱。利用 Kotlin 和 Compose Multiplatform,开发者能够在相同的开发环境中进行多平台开发,提升了开发者的体验和生产力。使用 Android Studio 和 Xcode 无缝集成,开发者可以在熟悉的 IDE 中进行跨平台开发和调试。
  • 现代化的 UI 构建
    Compose Multiplatform 基于声明式编程范式,简化了复杂的 UI 构建。开发者可以通过简明的代码定义动态界面,减少了样板代码和 UI 更新的复杂度。这种现代化的 UI 构建方式,不仅使代码更加清晰和易于维护,还提升了开发效率。
使用 KMM 和 Compose Multiplatform,开发团队可以在保证高性能和平台特性的同时,实现代码的最大复用和开发效率的提升。这种结合不仅为项目带来了显著的优势,还为开发者提供了创新和灵活的开发体验。
1. 基础概念

什么是 Kotlin Multiplatform (KMP)?
Kotlin Multiplatform (KMP) 是 JetBrains 提供的一项功能,允许使用 Kotlin 编写可以在多个平台上运行的代码。KMP 的目标是通过共享业务逻辑代码来减少不同平台开发的重复工作。KMP 支持的平台包括但不限于:
JVM:用于服务器端开发以及 Android 开发。
JavaScript:用于前端 Web 开发。
原生平台 (Native):如 iOS、Windows、macOS、Linux 等。
1.png

什么是 Kotlin Multiplatform Mobile (KMM)?
Kotlin Multiplatform Mobile (KMM) 是专注于移动平台的一种 KMP 实现。KMM 让开发者能够使用 Kotlin 编写可以在 Android 和 iOS 上运行的共享代码,主要关注点是在移动设备上的应用开发。简单来说,KMM 是 KMP 的一个子集或特化实现,专注于移动开发。
什么是 Compose multiform?
Compose Multiplatform 是 JetBrains 开发的一种跨平台用户界面 (UI) 框架,它基于 Kotlin 和 Jetpack Compose 的设计理念,旨在通过声明式编程范式简化 跨平台 UI 构建
什么是 Kotlin/Native、Kotlin/JVM、Kotlin/JS?与 KMP 的关系?
Kotlin 是一种现代化的编程语言,由 JetBrains 开发,支持多平台开发,包括 JVM、JavaScript 和原生平台。为了更高效地开发跨平台应用,Kotlin 提供了三种主要的编译器后端:Kotlin/JVM、Kotlin/JS 和 Kotlin/Native。
Kotlin/JVM 是最初的 Kotlin 编译器后端,也是最常用的一种。它将 Kotlin 代码编译成可以在 Java 虚拟机 (JVM) 上运行的字节码。由于 Kotlin 与 Java 高度互操作,Kotlin/JVM 可以直接利用现有的 Java 库和框架,使得开发者能够轻松地将 Kotlin 与 Java 项目集成。使用场景有 Android 开发与服务器开发。
Kotlin/JS 将 Kotlin 编译为 JavaScript 代码,从而可以在浏览器或 Node.js 环境中运行。Kotlin/JS 使得前端开发者可以使用 Kotlin 编写网页应用,同时充分利用现有的 JavaScript 库和框架。使用场景是 Web 前端开发。
Kotlin/Native 将 Kotlin 编译为原生二进制代码,可以直接运行在不依赖 JVM 或 JavaScript 引擎的环境中。Kotlin/Native 支持多种平台,包括 iOS、Windows、MacOS、Linux、嵌入式设备等,甚至于 Android、鸿蒙也可以使用 KN 跨平台开发(需要编写 JNI or NAPI 桥接代码)。KMP 结合了 Kotlin/JVM、Kotlin/JS 和 Kotlin/Native 的优势,使开发者能够在统一的代码库中,针对不同平台进行开发,实现跨平台方案。
2. KMP 核心原理

》https://www.cnblogs.com/liqw/p/15416758.html
2.1 特定于平台的 API 和实现

expect/actual 机制 :
KMM 里 expect/actual 机制是非常重要的,因为它提供了一种语法技术来解决平台相关的问题。举例来说,当我们需要在业务逻辑中使用设备的 model 号时,我们需要编写特定平台的代码才能实现。这时,expect 就相当于声明一个协议,它定义了我们期望得到的接口或数据,之后各个平台都需要独立地实现这个协议来满足业务需要。
可能会有人认为这样写了两遍,每个平台都写一遍不如让各个平台自己去写。但是,这种方式只需要建设一次,就像一些基础库一样只需要做一次就能在后面被大家共用。这种共用甚至不限于公司界,整个业界都可以共用一组基础库。
基本流程如下:在 commonMain 目录下建立一个 expect 类或 Top-Level 方法 , 类似创建一个协议声明。分别在 androidMain 和 iosMain 目录中,创建与 expect 声明(类名、方法名、参数类型及名称)完全一致的实现,否则编译器会报错。
1)平台抽象接口设计
  1. interface Platform { val name: String }
复制代码

  • 作用‌:定义跨平台共享的接口规范,声明所有平台必须实现的 name 属性,用于获取当前运行平台的名称(如“Android”“iOS”)‌。
  • 设计逻辑‌:通过接口强制各平台实现统一功能,保障代码在跨平台调用时的行为一致性‌。
2)多平台预期声明
  1. expect fun getPlatform(): Platform
复制代码

  • expect 关键字‌:声明一个需由各平台‌具体实现‌的公共函数,遵循 Kotlin Multiplatform 的 expect/actual 机制‌。
  • 函数功能‌:调用此函数将返回实现了 Platform 接口的平台专属对象,实现‌编译时多态‌‌。
3)平台专属实现示例
Android 端实现 (androidMain)‌:
  1. actual fun getPlatform(): Platform = AndroidPlatform()
  2. class AndroidPlatform : Platform {
  3.     override val name: String = "Android ${android.os.Build.VERSION.SDK_INT}"
  4. }
复制代码

  • actual 关键字‌:对应 expect 声明的具体实现,编译时根据目标平台自动匹配‌。
  • 实现细节‌:通过 Android SDK 获取系统版本号,增强平台特性识别能力‌。
iOS 端实现 (iosMain)‌:
  1. actual fun getPlatform(): Platform = IosPlatform()
  2. class IosPlatform : Platform {
  3.     override val name: String = UIDevice.currentDevice.systemName()
  4. }
复制代码

  • 平台交互‌:调用 iOS 原生 API UIDevice 获取设备信息,体现平台特定代码隔离原则‌。
4)核心设计模式

  • 分层架构‌:将‌平台无关逻辑‌置于 commonMain,‌平台相关实现‌隔离在 androidMain/iosMain 等目录‌。
  • 关注点分离‌:通过接口抽象和 expect/actual 机制,实现业务逻辑与平台特性的解耦,提升代码复用率‌。
该设计是 Kotlin Multiplatform 项目的典型结构,通过标准化的接口与平台适配层,支撑跨平台应用的统一功能开发‌。
2.2 直接访问 iOS Framework 的核心原理

KMM 项目中 iosMain 能直接访问 iOS Framework 的核心原理,主要依赖以下三层技术机制:
2.2.1 跨平台代码分层机制

通过 expect/actual 声明与实现分离:此机制实现‌接口统一声明、平台独立实现‌的架构‌。
2.2.2 CInterop 原生接口绑定

Kotlin/Native 通过 cinterop 工具生成 Objective-C/Swift 绑定的中间层:
1)生成绑定文件‌

  • 扫描 iOS Framework 的 .h 头文件。
  • 自动生成 Kotlin 可调用的 klib 接口文件(包含类/方法映射)‌。
2)Swift 兼容处理

  • Swift 方法需添加 @objc 修饰符,确保可被 Objective-C 运行时识别‌
  1. @objc class DeviceHelper: NSObject {
  2.     @objc static func getModel() -> String { /*...*/ }
  3. }
复制代码
2.2.3 编译期代码转换

Kotlin/Native 编译器将代码转换为 iOS 可识别的二进制格式:
1)编译阶段‌

  • iosMain 代码会被编译为 ‌Mach-O 格式‌的 Framework 或静态库‌。
  • 自动嵌入 Kotlin/Native 运行时(约 1MB)以支持跨平台特性‌。
2)产物集成

  • 输出 .framework 文件,包含:

    • 编译后的二进制代码。
    • Objective-C 头文件(自动生成)。
    • 资源文件(如有)‌。

  • Xcode 工程直接依赖该 Framework 即可调用‌。
2.2.4 整体交互流程和技术对比

整体交互流程:
  1. graph TD
  2.     A[Kotlin Common] -->|expect 声明| B(iosMain)
  3.     B -->|cinterop 绑定| C[iOS Framework]
  4.     C -->|编译为 Mach-O| D(Xcode 工程)
  5.     D -->|动态链接| E(UIKit 等系统框架)
复制代码
技术优势对比
特性KMM 实现方式传统跨平台方案‌API 调用方式‌直接访问原生 Framework‌通过桥接层间接调用‌性能损耗‌无额外运行时开销(原生二进制)‌常有解释器/JIT 损耗‌代码复用率‌逻辑层 100% 复用,UI 层独立‌全栈强制统一这一设计使得 KMM 在保持原生性能的同时,实现了逻辑代码的跨平台复用‌。
2.3 cinterop 生成中间层时机

Kotlin/Native 的 cinterop 工具生成 Objective-C/Swift 绑定的中间层,其生成时机和触发条件如下:
2.3.1 生成时机

1)编译期动态生成

  • 绑定文件‌不会在新建项目时自动生成‌,而是在‌首次执行构建任务‌(如运行 ./gradlew build)时触发生成流程‌。
  • 每次修改 .def 配置文件或原生头文件后,重新构建时会‌增量更新绑定文件‌‌。
2)条件触发机制

  • 仅当项目中声明了 cinterop 依赖且配置了原生框架调用时才会生成
    1. // build.gradle.kts 配置示例  
    2. kotlin {  
    3.     iosX64() {  
    4.         compilations.getByName("main") {  
    5.             cinterops.create("UIKit") {  
    6.                 defFile("src/nativeInterop/cinterop/UIKit.def")  
    7.             }  
    8.         }  
    9.     }  
    10. }  
    复制代码
    此时才会生成对应的 klib 和头文件‌
2.3.2 生成路径与产物

阶段产物路径文件类型‌初始生成‌build/bin/native/cinterop/.klib (Kotlin库)‌编译后集成‌build/bin/iosX64/debugFramework/.framework (二进制)‌头文件映射‌build/generated/cinterop/.h (Objective-C头文件)‌2.3.3 生成流程对比

项目状态绑定文件状态触发动作新建空项目❌ 未生成需手动配置 cinterop配置原生依赖后✅ 生成在构建目录执行 Gradle 构建任务更新头文件/配置后✅ 增量更新重新编译‌2.3.4 技术实现原理

1)‌构建管道集成‌:cinterop 作为 Kotlin/Native 编译管道的前置步骤,通过 Gradle 插件与构建系统深度集成‌。
  1. graph LR  
  2.     A[Gradle Task] --> B(cinterop 解析 .def 文件)  
  3.     B --> C(生成 .klib 和 .h)  
  4.     C --> D(Kotlin/Native 编译)  
复制代码
2)动态适配机制‌:当检测到 src/nativeInterop/cinterop 目录下的 .def 配置文件时,自动注册生成任务‌。
2.3.5 总结


  • 非预生成‌:绑定文件不会在新建项目时预生成,需通过构建任务触发。
  • 按需生成‌:仅在声明特定平台(如 iosMain)且配置原生依赖时生成‌。
  • 持续更新‌:头文件或配置变更后,通过重新编译实现动态更新‌
二. KMM 环境搭建

1. KDoctor

kdoctor 是一个用于验证 Kotlin Multiplatform Mobile (KMM) 开发环境是否正确配置的命令行工具。它会检查系统上的各种依赖和配置,确保已经安装并正确配置了所有必要的软件,例如 Android Studio、Xcode、CocoaPods 等。如果是第一次设置 KMM 环境,强烈建议使用 kdoctor 来确认一切都已正确配置。
安装 kdoctor
对于 macOS 系统:
确保 Homebrew 已安装 ,安装 kdoctor
  1. brew install kdoctor  
复制代码
使用 kdoctor 进行环境检查
安装完 kdoctor 后,通过以下命令检查 KMM 开发环境:
  1. kdoctor  
复制代码
kdoctor 将检查以下内容:
JDK:是否安装了 Java Development Kit。
Android Studio:是否安装了 Android Studio 和必要的组件。
Xcode:是否安装了 Xcode 和命令行工具。
CocoaPods:是否安装了 CocoaPods(用于管理 iOS 依赖)。
运行 kdoctor 后的示例输出:
  1. $ kdoctor  
  2. [ ✓ ] Checking the Java version (11.0.8).   
  3. [ ✓ ] Checking the Android Studio installation.   
  4. [ ✓ ] Checking the Xcode installation.   
  5. [ ✓ ] Checking the CocoaPods installation.   
  6. Conclusion:
  7.   ✓ Your operation system is ready for Kotlin Multiplatform Mobile Development!
复制代码
如果 kdoctor 报告某些组件未正确安装或配置,按照指导信息进行相应的操作来解决问题。在这个示例输出中,kdoctor 表明所有必要的软件都已正确安装,已准备好进行 KMM 开发。
2. Kotlin Multiplatform Plugin

在 Android Studio 中安装 Kotlin Multiplatform 插件:打开 Android Studio,进入 Settings -> Plugins,搜索并安装 Kotlin Multiplatform 插件,重启 Android Studio 以激活插件。
三. 项目构建和解析

》https://blog.csdn.net/logicsboy/article/details/128856861
1. 新建 KMM 项目

打开 Android Studio,选择 New Project。在项目模板中,选择 Kotlin Multiplatform App。配置项目名称、保存路径和包名。
2. 项目架构和配置

生成的 KMM 项目包含 Android 和 iOS 两个平台的代码,以及一个共享代码模块:
  1. Kmm/  
  2. ├── .gradle/ # 构建缓存文件
  3. ├── .idea/ # IDE 配置和元数据
  4. ├── android/ # Android 壳工程
  5. ├── gradle/  # gradle 环境管理
  6. ├── ios/     # iOS 壳工程
  7. ├── shared/  # 共享代码(业务、UI组件、资源)模块
  8. │   ├── build/
  9. │   ├── src/  
  10. │   │   ├── commonMain/ # 共享逻辑  
  11. │   │   ├── androidMain/  # Android 平台代码  
  12. │   │   ├── iosMain/     # iOS 平台代码  
  13. │   ├── build.gradle.kts
  14. │   ├── shared.podspec
  15. ├── .gitignore/ # Git 配置文件
  16. ├── build.gradle.kts/ # Gradle 构建工具的核心配置文件
  17. ├── gradle.properties/ # Gradle 构建工具的核心配置文件
  18. ├── gradlew/ # Gradle Wrapper 的启动脚本
  19. ├── gradlew.bat/ # Gradle Wrapper 的启动脚本
  20. ├── local.properties/ # 存储本地敏感配置禁止提交到版本控制
  21. └── settings.gradle.kts/ # Gradle 构建系统的核心配置文件
复制代码
.gradle 文件夹是 ‌Gradle 构建工具‌在运行过程中生成的缓存和临时文件目录,主要用于加速构建流程和管理项目依赖。
.idea IDE 配置和元数据,Android Studio 基于 IntelliJ IDEA 开发,所有项目(包括 KMM)在首次打开时都会自动生成 .idea 目录,用于加载和存储配置‌。
android 移动安卓壳工程。
gradle gradle 环境管理。

  • gradle-wrapper.jar‌:Gradle 环境启动器,实现版本自动化管理 ‌。负责根据 gradle-wrapper.properties 中定义的版本自动下载并安装指定版本的 Gradle‌。
  • gradle-wrapper.properties‌:定义所需的 Gradle 版本和下载源,保障跨环境一致性。
ios 移动 iOS 壳工程。
share 共享代码模块,目前仅包含业务逻辑,还可以添加 UI 组件、资源等。
.gitignore 是 Git 版本控制系统中一个 ‌纯文本配置文件‌,用于指定 Git 仓库中需要 ‌永久忽略跟踪‌ 的文件或目录。它的核心作用是 ‌过滤无需纳入版本控制的文件‌(如临时文件、编译产物、本地环境配置等),避免这些文件被意外提交到仓库中。
build.gradle.kts

  • KMM(Kotlin Multiplatform Mobile)项目中,build.gradle 文件是 ‌Gradle 构建工具‌的核心配置文件,用于定义项目的构建规则、依赖关系和插件设置
gradle.properties

  • 在 KMM(Kotlin Multiplatform Mobile)项目中,gradle.properties 文件是 ‌Gradle 构建工具的核心配置文件‌,用于定义全局属性、控制构建行为以及优化构建性能。
.gradlew   .gradlew.bat

  • 在新建 Kotlin Multiplatform Mobile (KMM) 项目时,生成的 ‌.gradlew‌(Unix/Linux/macOS)和 ‌.gradlew.bat‌(Windows)文件是 ‌Gradle Wrapper 的启动脚本‌。它们的作用是统一项目的构建环境,确保开发者无需预先安装特定版本的 Gradle,也能正确构建项目。
local.properties 存储本地敏感配置禁止提交到版本控制。
settings.gradle

  • 在 Kotlin Multiplatform Mobile (KMM) 项目中,settings.gradle 是 ‌Gradle 构建系统的核心配置文件‌,主要负责定义项目结构、管理子模块和配置构建行为‌‌。
四. 配置文件详解

1. build.gradle

在 KMM(Kotlin Multiplatform Mobile)项目中,build.gradle 文件是 ‌Gradle 构建工具‌的核心配置文件,用于定义项目的构建规则(逻辑)、模块级依赖关系和插件设置、任务等构建逻辑,属于代码的一部分。以下是它在 KMM 项目中的具体作用:定义构建逻辑、依赖关系。
1.1 build.gradle 的作用

Gradle 使用 build.gradle 文件来配置:

  • 项目级设置‌:定义整个项目的构建规则、公共插件、仓库和依赖版本。
  • 模块级设置‌:针对每个子模块(如共享模块、Android App、iOS 框架)配置构建规则。
  • 多平台支持‌:声明 Kotlin Multiplatform 的目标平台(Android、iOS、JVM 等)。
  • 依赖管理‌:声明项目所需的库(如 Kotlin 标准库、第三方库)。
1.‌2 KMM 项目的典型结构

一个 KMM 项目通常包含以下 build.gradle 文件。
1.2.1 项目根目录的 build.gradle


  • 作用‌:全局配置,定义构建工具、以及所有子模块共享的规则。
  • ‌示例:
    1. // 根项目的 build.gradle
    2. // 构建工具本身,构建初始化阶段
    3. buildscript {
    4.     repositories {
    5.         google()
    6.         mavenCentral()
    7.     }
    8.     dependencies {
    9.         // 定义全局使用的 Gradle 插件版本(如 Android 插件、Kotlin 插件)
    10.         classpath "com.android.tools.build:gradle:7.0.4"
    11.         classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10"
    12.     }
    13. }
    14. // 所有子模块共享的配置,配置模块的业务依赖仓库地址,项目配置阶段。项目模块的实际依赖(如 implementation、api)应写在‌模块级‌ build.gradle 中,而非 allprojects 块内
    15. allprojects {
    16.     repositories {
    17.         google()
    18.         mavenCentral()
    19.     }
    20. }
    21. // 根项目自身‌(非子模块)        根项目需单独使用的插件或依赖        根项目解析阶段。若根项目无特殊依赖需求,可省略单独 repositories 块,避免冗余
    22. repositories {
    23.     mavenCentral()
    24. }
    复制代码
1.2.2 共享模块的 build.gradle


  • 作用‌:配置跨平台代码的构建规则(如 Android 和 iOS 的共享逻辑)。
  • ‌示例:
    1. // 共享模块的 build.gradle
    2. plugins {
    3.     id 'org.jetbrains.kotlin.multiplatform'
    4. }
    5. // 定义目标平台:声明编译目标、启用多平台特性、配置平台专属依赖
    6. kotlin {
    7.     // 定义多平台目标
    8.     android()  // Android 平台
    9.     iosArm64 { // iOS 设备(ARM64)
    10.         binaries.framework { // 生成 iOS 框架
    11.             baseName = "Shared"
    12.         }
    13.     }
    14.     sourceSets {} // 源集配置
    15. }
    16. // Android 特定配置
    17. android {
    18.     compileSdkVersion 31
    19.     defaultConfig {
    20.         minSdkVersion 21
    21.         targetSdkVersion 31
    22.     }
    23. }
    24. // 依赖声明
    25. dependencies {
    26.     // 公共依赖(所有平台共享)
    27.     commonMain.dependencies {
    28.         implementation "org.jetbrains.kotlin:kotlin-stdlib-common"
    29.     }
    30.     // Android 专属依赖
    31.     androidMain.dependencies {
    32.         implementation "org.jetbrains.kotlin:kotlin-stdlib"
    33.     }
    34. }
    复制代码
1.2.3 Android App 模块的 build.gradle


  • 作用‌:配置 Android 应用的构建规则。
  • ‌示例:
    1. plugins {
    2.     id 'com.android.application'
    3.     id 'kotlin-android'
    4. }
    5. android {
    6.     compileSdk 31
    7.     defaultConfig {
    8.         applicationId "com.example.kmmapp"
    9.         minSdk 21
    10.         targetSdk 31
    11.     }
    12. }
    13. dependencies {
    14.     implementation project(":shared")  // 依赖共享模块
    15.     implementation "androidx.core:core-ktx:1.7.0"
    16. }
    复制代码
1.2.4 iOS 模块的配置‌

说明‌:iOS 代码通常通过共享模块生成的框架(.framework)集成到 Xcode 项目,无需单独的 build.gradle。
‌1.3 关键配置解析‌

1)多平台目标声明
通过 kotlin { ... } 块定义支持的平台:
  1. kotlin {
  2.     android()       // Android 平台
  3.     iosArm64()      // iOS 真机 (ARM64)
  4.     iosSimulatorArm64() // iOS 模拟器 (Apple Silicon)
  5.     jvm()           // JVM 平台(可选)
  6. }
复制代码
2) 依赖分类‌\定义依赖项
KMM 支持按平台细分依赖:
  1. dependencies {
  2.     // 公共依赖(所有平台共享)
  3.     commonMain.dependencies {
  4.         implementation "io.ktor:ktor-client-core:2.0.0"
  5.     }
  6.     // Android 专属依赖
  7.     androidMain.dependencies {
  8.         implementation "io.ktor:ktor-client-android:2.0.0"
  9.     }
  10.     // iOS 专属依赖
  11.     iosMain.dependencies {
  12.         implementation "io.ktor:ktor-client-ios:2.0.0"
  13.     }
  14. }
复制代码
3) iOS 框架生成
配置共享模块生成 iOS 可用的框架:
  1. kotlin {
  2.     iosArm64 {
  3.         binaries.framework {
  4.             baseName = "Shared"  // 框架名称
  5.             export(project(":shared")) // 导出其他模块(可选)
  6.         }
  7.     }
  8. }
复制代码
4) 定义插件 Plugins
  1. plugins {
  2.     id("com.android.application")
  3.     kotlin("android")
  4. }
复制代码
1.‌4 常见问题与解决

1) 依赖解析失败

  • 表现‌:Could not resolve ... 错误。
  • ‌解决:

    • 检查仓库是否包含 google() 和 mavenCentral()。
    • 确保网络可以访问仓库(国内可尝试阿里云镜像)。

2) 插件版本冲突

  • 表现‌:Unsupported Kotlin plugin version。
  • ‌解决:统一 Kotlin 插件版本:
    1. // 根项目的 build.gradle
    2. classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10"
    复制代码
3) iOS 构建失败

  • 表现‌:Framework not found。
  • ‌解决‌:

    • 运行 ./gradlew :shared:packForXcode 重新生成框架。
    • 在 Xcode 中清理构建缓存(Product > Clean Build Folder)。

1.‌5 总结‌

build.gradle 在 KMM 项目中是构建流程的核心控制器‌,负责:

  • 定义多平台目标和编译规则。
  • 管理跨平台依赖。
  • 集成 Android 和 iOS 的构建配置。
  • 生成 iOS 框架供 Xcode 使用。
通过合理配置 build.gradle,你可以实现一套代码在 Android 和 iOS 之间的高效共享,同时保持平台特定逻辑的灵活性。
2.  gradle.properties

在 KMM(Kotlin Multiplatform Mobile)项目中,gradle.properties 文件是 ‌Gradle 构建工具的核心配置文件‌,用于定义全局属性(变量)、控制构建环境(Gradle 运行参数,主要用于定义行为和优化构建性能)。它在 Android Studio 项目中扮演以下关键角色。
2.1 ‌配置 Gradle 构建环境

通过 gradle.properties,你可以调整 Gradle 本身的运行参数:

  • ‌JVM 内存分配:优化构建速度,避免内存溢出。
    1. # 增加 Gradle 堆内存
    2. org.gradle.jvmargs=-Xmx4096m -Dfile.encoding=UTF-8
    复制代码
  • ‌启用构建缓存‌:加速重复构建。
    1. # 开启缓存
    2. org.gradle.caching=true
    复制代码
  • ‌并行执行和多项目构建:
    1. # 并行执行任务
    2. org.gradle.parallel=true
    3. # 多项目构建优化
    4. org.gradle.configureondemand=true
    复制代码
2.2 ‌定义项目全局变量

在 gradle.properties 中定义的变量,可以在所有模块的 build.gradle.kts 或 build.gradle 文件中直接引用,方便统一管理版本号和通用配置:
  1. # 定义公共版本号
  2. kotlin_version=1.8.21
  3. androidGradlePlugin_version=7.4.2
复制代码
在 build.gradle.kts 中使用:
  1. plugins {            kotlin("multiplatform").version(project.property("kotlin_version") as String)
  2. }
复制代码
2.3 ‌控制 KMM 多平台构建行为

KMM 项目依赖 Kotlin/Native 编译器,gradle.properties 可以配置 Native 编译参数:
  1. # 启用 Kotlin/Native 内存模型(新版本默认启用)
  2. kotlin.native.binary.memoryModel=strict
  3. # 禁用 iOS 模拟器 arm64 目标(解决 M1/M2 芯片兼容性问题)
  4. kotlin.native.disableCompilerDaemon=true
复制代码
2.4 ‌管理 Android 和 iOS 构建配置


  • ‌Android 构建优化:
    1. # 启用 Android Jetpack Compose
    2. android.enableCompose=true
    3. # 禁用不必要的 Lint 检查
    4. android.enableBuildCache=true
    复制代码
  • ‌iOS 构建配置:
    1. # 指定 Xcode 兼容版本
    2. kotlin.ios.teamId=XXXXXXXXXX
    复制代码
2.‌5. ‌配置代理和仓库镜像

解决国内依赖下载慢的问题:
  1. # 使用阿里云镜像加速
  2. systemProp.http.proxyHost=mirrors.aliyun.com
  3. systemProp.http.proxyPort=80
  4. systemProp.https.proxyHost=mirrors.aliyun.com
  5. systemProp.https.proxyPort=80
复制代码
2.6 ‌启用实验性功能

对于 KMM 或 Kotlin 的实验性特性,需在此显式启用:
  1. # 启用 Kotlin 新内存管理器(跨平台内存共享)
  2. kotlin.native.enableExperimentalMemoryManager=true
  3. # 启用 Jetpack Compose Multiplatform
  4. org.jetbrains.compose.experimental.kotlin.multiplatform=true
复制代码
2.7 ‌解决常见构建问题

通过 gradle.properties 快速修复构建错误:

  • ‌Kotlin/Native 编译器版本冲突:
    1. kotlin.native.version=1.8.21
    复制代码
  • ‌禁用 Precompiled Script Plugins(旧版本 Gradle 兼容):
    1. org.gradle.unsafe.allow-incompatible-plugins=false
    复制代码
2.8 文件位置与优先级‌


  • 项目级‌:/gradle.properties
    仅影响当前项目。
  • 全局级‌:~/.gradle/gradle.properties
    影响所有 Gradle 项目(谨慎使用)。
2.9 KMM 项目典型配置示例
  1. # Gradle 配置
  2. org.gradle.jvmargs=-Xmx4096m -Dfile.encoding=UTF-8
  3. org.gradle.caching=true
  4. # Kotlin 版本
  5. kotlin_version=1.8.21
  6. # Android 配置
  7. android.useAndroidX=true
  8. android.enableCompose=true
  9. # KMM/Native 配置
  10. kotlin.native.binary.memoryModel=strict
  11. kotlin.mpp.enableGranularSourceSetsMetadata=true
  12. # 国内镜像加速
  13. systemProp.http.proxyHost=mirrors.aliyun.com
  14. systemProp.https.proxyHost=mirrors.aliyun.com
复制代码
注意事项:

  • 键值对格式‌:必须使用 key=value 格式,且不能有多余的空格。
  • 类型限制‌:所有值均为字符串,需在 build.gradle.kts 中按需转换类型。
  • 版本兼容性‌:部分属性(如 kotlin.native.binary.memoryModel)需与 Kotlin 版本匹配,否则构建会失败。
通过合理配置 gradle.properties,你可以显著提升 KMM 项目的构建性能和跨平台开发体验。
3. local.properties

local.properties 是本地开发环境专属的配置文件‌,主要用于存储与开发者机器强相关的路径、密钥等敏感信息,避免将这些内容暴露在版本控制中(禁止提交到版本控制)。以下是其核心功能与使用规范:
3.1 核心作用‌

1)配置本地开发环境路径


  • 定义 Android SDK、NDK 的本地路径(不同开发者机器路径不同)‌。
    1. sdk.dir=/Users/xxx/Library/Android/sdk  
    2. ndk.dir=/Users/xxx/Library/Android/ndk  
    复制代码
  • 用于 Gradle 构建时自动识别 Android 开发环境依赖‌。
2)存储敏感信息‌


  • 本地调试密钥路径及密码‌:
    1. debug.keystore=/path/to/debug.keystore  
    2. keyAlias=debug  
    3. keyPassword=123456  
    4. storePassword=123456  
    复制代码
  • 私有 API 密钥或其他环境变量(如测试服务器地址)‌。
3)隔离团队协作差异


  • 避免因开发者本地环境差异(如 SDK 路径)导致构建失败,文件默认不提交至 Git 等版本控制系统‌。
3.2 典型配置内容

配置项‌‌示例值‌‌用途‌sdk.dir/Users/xxx/Library/Android/sdk指定 Android SDK 安装路径‌。ndk.dir/Users/xxx/Library/Android/ndk/5.2.9指定 NDK 路径(如需使用 JNI/Native 代码)‌。debug.keystore/path/to/debug.keystore本地调试 APK 的签名文件路径‌。custom.api.keyyour_private_key自定义 API 密钥(如地图服务、支付 SDK)‌。3.3 ‌在 KMM 项目中的使用方式

1)‌读取配置


  • 在 build.gradle 中通过代码读取配置(以 Android 模块为例)‌:
    1. def localProperties = new Properties()  
    2. localProperties.load(new FileInputStream(rootProject.file("local.properties")))  
    3. android {  
    4.     signingConfigs {  
    5.         debug {  
    6.             storeFile file(localProperties["debug.keystore"])  
    7.             storePassword localProperties["storePassword"]  
    8.             keyAlias localProperties["keyAlias"]  
    9.             keyPassword localProperties["keyPassword"]  
    10.         }  
    11.     }  
    12. }  
    复制代码
2)动态注入环境变量


  • 通过 Gradle 参数传递 local.properties 中的值到代码中(如 API 密钥)‌:
    1. android {  
    2.     defaultConfig {  
    3.         buildConfigField "String", "API_KEY", ""${localProperties["api.key"]}""  
    4.     }  
    5. }  
    复制代码
    在代码中通过访问:
    1. BuildConfig.API_KEY
    复制代码
3.4 ‌最佳实践


  • ‌禁止提交至版本控制
    将 local.properties 加入 .gitignore,防止敏感信息泄露‌。
  • ‌提供模板文件
    ‌创建 local.properties.template 并提交,指导团队成员复制后填写本地路径‌。
  • ‌统一环境管理
    ‌团队协作时,通过文档说明配置项含义及填写规范(如 SDK 版本要求)‌。
3.5 与 gradle.properties 的区别

对比项‌local.propertiesgradle.properties‌作用范围‌仅本地环境生效全局项目生效(所有开发者共享)‌。‌典型内容‌SDK 路径、密钥等敏感信息JVM 内存、构建缓存开关、插件版本‌。‌是否共享‌否是总结‌:local.properties 是 KMM 项目中用于隔离本地环境差异的核心文件,通过存储敏感信息和机器特定路径,确保团队协作时构建流程的稳定性和安全性‌
4. settings.gradle

在 Kotlin Multiplatform Mobile (KMM) 项目中,settings.gradle 是 ‌Gradle 构建系统的核心配置文件‌,主要负责定义项目结构、管理子模块和配置构建行为‌‌。以下是其核心作用:
4.1 声明项目包含的模块


  • ‌核心功能:通过 include 函数明确项目中包含哪些子模块(如共享代码模块、Android/iOS 平台模块)‌。示例代码‌(KMM 典型配置):
    1. // 包含共享模块、Android 和 iOS 平台模块
    2. include ':shared', ':androidApp', ':iosApp'
    复制代码
  • 多平台适配‌:在 KMM 中,通常将跨平台逻辑放在 shared 模块,并通过 include 声明其与平台模块的关联‌。
4.2 定义模块路径


  • ‌调整模块路径:若模块不在默认路径下(如将 iOS 模块放在 ios 目录),需通过 project 函数指定路径‌。示例:
    1. include ':shared', ':androidApp'
    2. // 指定 iOS 模块路径
    3. project(':iosApp').projectDir = new File('ios/application')
    复制代码
4.3 配置插件和仓库


  • ‌插件版本管理:在 KMM 中,需统一 Kotlin 插件版本以兼容多平台构建‌。示例:
    1. pluginManagement {
    2.     repositories {
    3.         google()
    4.         mavenCentral()
    5.         gradlePluginPortal()
    6.     }
    7.     // 指定 Kotlin 和 Android 插件版本
    8.     plugins {
    9.         id 'org.jetbrains.kotlin.multiplatform' version '1.9.20'
    10.         id 'com.android.application' version '8.1.0'
    11.     }
    12. }
    复制代码
4.4 管理依赖解析策略


  • ‌统一依赖仓库:声明全局仓库地址(如 Maven Central、Google 仓库),确保所有模块使用相同的依赖源‌。示例‌:
    1. dependencyResolutionManagement {
    2.     repositories {
    3.         google()
    4.         mavenCentral()
    5.     }
    6. }
    复制代码
4.5 KMM 项目中的特殊作用


  • 多平台模块协调‌:确保共享模块(shared)与平台模块(androidApp、iosApp)的依赖关系正确传递‌。
  • 构建环境隔离‌:通过插件管理避免不同平台(如 Android 和 iOS)的构建冲突‌。
总结:settings.gradle 在 KMM 项目中是多模块和多平台构建的基石‌,通过声明模块、管理路径和统一配置,确保跨平台代码与原生模块的高效整合‌。其配置直接影响 Gradle 如何识别和组织项目结构,是跨平台开发的关键文件之一。
5. gradlew

在新建 Kotlin Multiplatform Mobile (KMM) 项目时,生成的 ‌.gradlew‌(Unix/Linux/macOS)和 ‌.gradlew.bat‌(Windows)文件是 ‌Gradle Wrapper 的启动脚本‌。它们的作用是统一项目的构建环境,确保开发者无需预先安装特定版本的 Gradle,也能正确构建项目。以下是详细解析:
5.1 Gradle Wrapper 的核心作用


  • 环境一致性‌:无论开发者本地安装的 Gradle 版本是什么,项目都通过 Wrapper 使用 ‌gradle-wrapper.properties‌ 中指定的 Gradle 版本进行构建,避免版本冲突。
  • 零配置运行‌:新克隆项目的开发者无需手动安装 Gradle,直接运行 Wrapper 脚本即可自动下载并配置正确的 Gradle 版本。
5.2 文件的作用‌

文件名平台功能gradlewUnix/Linux/macOSShell 脚本,用于执行 Gradle 命令(如 ./gradlew build)gradlew.batWindows批处理脚本,功能同上(如 gradlew.bat build)gradle/wrapper/ 目录所有平台包含 Wrapper 的核心文件(如 gradle-wrapper.jar 和 gradle-wrapper.properties)5.3 核心文件解析‌

1)‌gradle-wrapper.properties
位于 gradle/wrapper/gradle-wrapper.properties,定义了 Gradle 的下载地址和版本‌:
  1. # 指定使用的 Gradle 发行版类型(通常是 'bin' 或 'all')
  2. distributionType=bin
  3. # 指定 Gradle 版本(必须与项目兼容)
  4. distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
复制代码

  • bin‌:仅包含运行时(体积小,适合大多数场景)。
  • all‌:包含文档和源码(适用于需要调试 Gradle 的场景)。
2)‌gradle-wrapper.jar
位于 gradle/wrapper/gradle-wrapper.jar,是 Wrapper 的核心实现,负责 ‌下载并安装指定版本的 Gradle‌。
5.4. 如何使用 Wrapper 脚本?

1)‌Unix/Linux/macOS
  1. # 运行构建命令
  2. ./gradlew build
  3. # 清理构建缓存
  4. ./gradlew clean
  5. # 更新 Gradle 版本(修改 gradle-wrapper.properties 后)
  6. ./gradlew wrapper --gradle-version=8.5
复制代码
2)Windows
  1. # 运行构建命令
  2. gradlew.bat build
  3. # 清理构建缓存
  4. gradlew.bat clean
复制代码
5.5 为何需要提交这些文件到版本控制?


  • 确保一致性‌:所有开发者使用相同的 Gradle 版本和配置。
  • 简化协作‌:新成员无需手动安装或配置 Gradle,直接运行 Wrapper 即可。
5.6 常见问题‌

1)‌Q1:gradlew 权限被拒绝?

  • ‌解决方法:赋予执行权限:
    1. chmod +x gradlew
    复制代码
2)Q2:如何更新 Gradle 版本?

  • 修改 gradle-wrapper.properties 中的 distributionUrl。
  • 运行 Wrapper 任务以下载新版本:
    1. ./gradlew wrapper --gradle-version=8.5
    复制代码
3)Q3:gradlew 文件被误删怎么办?

  • ‌恢复方法:重新生成 Wrapper;
》https://coderyuan.com/2021/05/28/KMM-2/
》https://cloud.tencent.com/developer/article/1909223
》https://news.qq.com/rain/a/20230324A04YF900

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册