任何事情,急于求成都是幼稚的幻想,急于求成的结果一定是不成,对此不应该有任何怀疑。
一. 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 等。

什么是 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)平台抽象接口设计
kotlin
interface Platform { val name: String }
- 作用 :定义跨平台共享的接口规范,声明所有平台必须实现的
name
属性,用于获取当前运行平台的名称(如"Android""iOS")。 - 设计逻辑:通过接口强制各平台实现统一功能,保障代码在跨平台调用时的行为一致性。
2)多平台预期声明
kotlin
expect fun getPlatform(): Platform
- expect 关键字 :声明一个需由各平台具体实现 的公共函数,遵循 Kotlin Multiplatform 的
expect/actual
机制。 - 函数功能 :调用此函数将返回实现了
Platform
接口的平台专属对象,实现编译时多态。
3)平台专属实现示例
**Android 端实现 (androidMain
)**:
kotlin
actual fun getPlatform(): Platform = AndroidPlatform()
class AndroidPlatform : Platform {
override val name: String = "Android ${android.os.Build.VERSION.SDK_INT}"
}
- actual 关键字 :对应
expect
声明的具体实现,编译时根据目标平台自动匹配。 - 实现细节:通过 Android SDK 获取系统版本号,增强平台特性识别能力。
**iOS 端实现 (iosMain
)**:
kotlin
actual fun getPlatform(): Platform = IosPlatform()
class IosPlatform : Platform {
override val name: String = UIDevice.currentDevice.systemName()
}
- 平台交互 :调用 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 运行时识别@objc class DeviceHelper: NSObject {
@objc static func getModel() -> String { /.../ }
}
2.2.3 编译期代码转换
Kotlin/Native 编译器将代码转换为 iOS 可识别的二进制格式:
1)编译阶段
iosMain
代码会被编译为 Mach-O 格式的 Framework 或静态库。- 自动嵌入 Kotlin/Native 运行时(约 1MB)以支持跨平台特性。
2)产物集成
-
输出
.framework
文件,包含:- 编译后的二进制代码。
- Objective-C 头文件(自动生成)。
- 资源文件(如有)。
-
Xcode 工程直接依赖该 Framework 即可调用。
2.2.4 整体交互流程和技术对比
整体交互流程:
graph TD
A[Kotlin Common] -->|expect 声明| B(iosMain)
B -->|cinterop 绑定| C[iOS Framework]
C -->|编译为 Mach-O| D(Xcode 工程)
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
依赖且配置了原生框架调用时才会生成kotlin// build.gradle.kts 配置示例 kotlin { iosX64() { compilations.getByName("main") { cinterops.create("UIKit") { defFile("src/nativeInterop/cinterop/UIKit.def") } } } }
此时才会生成对应的
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 插件与构建系统深度集成。
graph LR
A[Gradle Task] --> B(cinterop 解析 .def 文件)
B --> C(生成 .klib 和 .h)
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
shell
brew install kdoctor
使用 kdoctor 进行环境检查
安装完 kdoctor 后,通过以下命令检查 KMM 开发环境:
shell
kdoctor
kdoctor 将检查以下内容:
JDK
:是否安装了 Java Development Kit。
Android Studio
:是否安装了 Android Studio 和必要的组件。
Xcode
:是否安装了 Xcode 和命令行工具。
CocoaPods
:是否安装了 CocoaPods(用于管理 iOS 依赖)。
运行 kdoctor 后的示例输出:
csharp
$ kdoctor
[ ✓ ] Checking the Java version (11.0.8).
[ ✓ ] Checking the Android Studio installation.
[ ✓ ] Checking the Xcode installation.
[ ✓ ] Checking the CocoaPods installation.
Conclusion:
✓ 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 两个平台的代码,以及一个共享代码模块:
bash
Kmm/
├── .gradle/ # 构建缓存文件
├── .idea/ # IDE 配置和元数据
├── android/ # Android 壳工程
├── gradle/ # gradle 环境管理
├── ios/ # iOS 壳工程
├── shared/ # 共享代码(业务、UI组件、资源)模块
│ ├── build/
│ ├── src/
│ │ ├── commonMain/ # 共享逻辑
│ │ ├── androidMain/ # Android 平台代码
│ │ ├── iosMain/ # iOS 平台代码
│ ├── build.gradle.kts
│ ├── shared.podspec
├── .gitignore/ # Git 配置文件
├── build.gradle.kts/ # Gradle 构建工具的核心配置文件
├── gradle.properties/ # Gradle 构建工具的核心配置文件
├── gradlew/ # Gradle Wrapper 的启动脚本
├── gradlew.bat/ # Gradle Wrapper 的启动脚本
├── local.properties/ # 存储本地敏感配置禁止提交到版本控制
└── 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
-
作用:全局配置,定义构建工具、以及所有子模块共享的规则。
-
示例:
// 根项目的 build.gradle // 构建工具本身,构建初始化阶段 buildscript { repositories { google() mavenCentral() } dependencies { // 定义全局使用的 Gradle 插件版本(如 Android 插件、Kotlin 插件) classpath "com.android.tools.build:gradle:7.0.4" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10" } } // 所有子模块共享的配置,配置模块的业务依赖仓库地址,项目配置阶段。项目模块的实际依赖(如 implementation、api)应写在模块级 build.gradle 中,而非 allprojects 块内 allprojects { repositories { google() mavenCentral() } } // 根项目自身(非子模块) 根项目需单独使用的插件或依赖 根项目解析阶段。若根项目无特殊依赖需求,可省略单独 repositories 块,避免冗余 repositories { mavenCentral() }
1.2.2 共享模块的 build.gradle
-
作用:配置跨平台代码的构建规则(如 Android 和 iOS 的共享逻辑)。
-
示例:
// 共享模块的 build.gradle plugins { id 'org.jetbrains.kotlin.multiplatform' } // 定义目标平台:声明编译目标、启用多平台特性、配置平台专属依赖 kotlin { // 定义多平台目标 android() // Android 平台 iosArm64 { // iOS 设备(ARM64) binaries.framework { // 生成 iOS 框架 baseName = "Shared" } } sourceSets {} // 源集配置 } // Android 特定配置 android { compileSdkVersion 31 defaultConfig { minSdkVersion 21 targetSdkVersion 31 } } // 依赖声明 dependencies { // 公共依赖(所有平台共享) commonMain.dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-common" } // Android 专属依赖 androidMain.dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib" } }
1.2.3 Android App 模块的 build.gradle
-
作用:配置 Android 应用的构建规则。
-
示例:
plugins { id 'com.android.application' id 'kotlin-android' } android { compileSdk 31 defaultConfig { applicationId "com.example.kmmapp" minSdk 21 targetSdk 31 } } dependencies { implementation project(":shared") // 依赖共享模块 implementation "androidx.core:core-ktx:1.7.0" }
1.2.4 iOS 模块的配置
说明 :iOS 代码通常通过共享模块生成的框架(.framework
)集成到 Xcode 项目,无需单独的 build.gradle
。
1.3 关键配置解析
1)多平台目标声明
通过 kotlin { ... }
块定义支持的平台:
kotlin {
android() // Android 平台
iosArm64() // iOS 真机 (ARM64)
iosSimulatorArm64() // iOS 模拟器 (Apple Silicon)
jvm() // JVM 平台(可选)
}
2) 依赖分类\定义依赖项
KMM 支持按平台细分依赖:
dependencies {
// 公共依赖(所有平台共享)
commonMain.dependencies {
implementation "io.ktor:ktor-client-core:2.0.0"
}
// Android 专属依赖
androidMain.dependencies {
implementation "io.ktor:ktor-client-android:2.0.0"
}
// iOS 专属依赖
iosMain.dependencies {
implementation "io.ktor:ktor-client-ios:2.0.0"
}
}
3) iOS 框架生成
配置共享模块生成 iOS 可用的框架:
kotlin {
iosArm64 {
binaries.framework {
baseName = "Shared" // 框架名称
export(project(":shared")) // 导出其他模块(可选)
}
}
}
4) 定义插件 Plugins
plugins {
id("com.android.application")
kotlin("android")
}
1.4 常见问题与解决
1) 依赖解析失败
-
表现 :
Could not resolve ...
错误。 -
解决:
- 检查仓库是否包含
google()
和mavenCentral()
。 - 确保网络可以访问仓库(国内可尝试阿里云镜像)。
- 检查仓库是否包含
2) 插件版本冲突
-
表现 :
Unsupported Kotlin plugin version
。 -
解决:统一 Kotlin 插件版本:
// 根项目的 build.gradle 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 内存分配:优化构建速度,避免内存溢出。
# 增加 Gradle 堆内存 org.gradle.jvmargs=-Xmx4096m -Dfile.encoding=UTF-8
-
启用构建缓存:加速重复构建。
# 开启缓存 org.gradle.caching=true
-
并行执行和多项目构建:
# 并行执行任务 org.gradle.parallel=true # 多项目构建优化 org.gradle.configureondemand=true
2.2 定义项目全局变量
在 gradle.properties
中定义的变量,可以在所有模块的 build.gradle.kts
或 build.gradle
文件中直接引用,方便统一管理版本号和通用配置:
# 定义公共版本号
kotlin_version=1.8.21
androidGradlePlugin_version=7.4.2
在 build.gradle.kts
中使用:
plugins { kotlin("multiplatform").version(project.property("kotlin_version") as String)
}
2.3 控制 KMM 多平台构建行为
KMM 项目依赖 Kotlin/Native 编译器,gradle.properties
可以配置 Native 编译参数:
# 启用 Kotlin/Native 内存模型(新版本默认启用)
kotlin.native.binary.memoryModel=strict
# 禁用 iOS 模拟器 arm64 目标(解决 M1/M2 芯片兼容性问题)
kotlin.native.disableCompilerDaemon=true
2.4 管理 Android 和 iOS 构建配置
-
Android 构建优化:
# 启用 Android Jetpack Compose android.enableCompose=true # 禁用不必要的 Lint 检查 android.enableBuildCache=true
-
iOS 构建配置:
# 指定 Xcode 兼容版本 kotlin.ios.teamId=XXXXXXXXXX
2.5. 配置代理和仓库镜像
解决国内依赖下载慢的问题:
# 使用阿里云镜像加速
systemProp.http.proxyHost=mirrors.aliyun.com
systemProp.http.proxyPort=80
systemProp.https.proxyHost=mirrors.aliyun.com
systemProp.https.proxyPort=80
2.6 启用实验性功能
对于 KMM 或 Kotlin 的实验性特性,需在此显式启用:
# 启用 Kotlin 新内存管理器(跨平台内存共享)
kotlin.native.enableExperimentalMemoryManager=true
# 启用 Jetpack Compose Multiplatform
org.jetbrains.compose.experimental.kotlin.multiplatform=true
2.7 解决常见构建问题
通过 gradle.properties
快速修复构建错误:
-
Kotlin/Native 编译器版本冲突:
kotlin.native.version=1.8.21
-
禁用 Precompiled Script Plugins(旧版本 Gradle 兼容):
org.gradle.unsafe.allow-incompatible-plugins=false
2.8 文件位置与优先级
- 项目级 :
<project-root>/gradle.properties
仅影响当前项目。 - 全局级 :
~/.gradle/gradle.properties
影响所有 Gradle 项目(谨慎使用)。
2.9 KMM 项目典型配置示例
# Gradle 配置
org.gradle.jvmargs=-Xmx4096m -Dfile.encoding=UTF-8
org.gradle.caching=true
# Kotlin 版本
kotlin_version=1.8.21
# Android 配置
android.useAndroidX=true
android.enableCompose=true
# KMM/Native 配置
kotlin.native.binary.memoryModel=strict
kotlin.mpp.enableGranularSourceSetsMetadata=true
# 国内镜像加速
systemProp.http.proxyHost=mirrors.aliyun.com
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 的本地路径(不同开发者机器路径不同)。
sdk.dir=/Users/xxx/Library/Android/sdk ndk.dir=/Users/xxx/Library/Android/ndk
-
用于 Gradle 构建时自动识别 Android 开发环境依赖。
2)存储敏感信息
-
本地调试密钥路径及密码:
debug.keystore=/path/to/debug.keystore keyAlias=debug keyPassword=123456 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.key |
your_private_key |
自定义 API 密钥(如地图服务、支付 SDK)。 |
3.3 在 KMM 项目中的使用方式
1)读取配置
-
在 build.gradle 中通过代码读取配置(以 Android 模块为例):
def localProperties = new Properties() localProperties.load(new FileInputStream(rootProject.file("local.properties"))) android { signingConfigs { debug { storeFile file(localProperties["debug.keystore"]) storePassword localProperties["storePassword"] keyAlias localProperties["keyAlias"] keyPassword localProperties["keyPassword"] } } }
2)动态注入环境变量
-
通过 Gradle 参数传递 local.properties 中的值到代码中(如 API 密钥):
android { defaultConfig { buildConfigField "String", "API_KEY", "\"${localProperties["api.key"]}\"" } }
在代码中通过访问:
BuildConfig.API_KEY
3.4 最佳实践
-
禁止提交至版本控制
将
local.properties
加入.gitignore
,防止敏感信息泄露。 -
提供模板文件
创建
local.properties.template
并提交,指导团队成员复制后填写本地路径。 -
统一环境管理
团队协作时,通过文档说明配置项含义及填写规范(如 SDK 版本要求)。
3.5 与 gradle.properties
的区别
对比项 | local.properties |
gradle.properties |
---|---|---|
作用范围 | 仅本地环境生效 | 全局项目生效(所有开发者共享)。 |
典型内容 | SDK 路径、密钥等敏感信息 | JVM 内存、构建缓存开关、插件版本。 |
是否共享 | 否 | 是 |
总结 :local.properties
是 KMM 项目中用于隔离本地环境差异的核心文件,通过存储敏感信息和机器特定路径,确保团队协作时构建流程的稳定性和安全性
4. settings.gradle
在 Kotlin Multiplatform Mobile (KMM) 项目中,settings.gradle
是 Gradle 构建系统的核心配置文件 ,主要负责定义项目结构、管理子模块和配置构建行为。以下是其核心作用:
4.1 声明项目包含的模块
-
核心功能:通过 include 函数明确项目中包含哪些子模块(如共享代码模块、Android/iOS 平台模块)。示例代码(KMM 典型配置):
// 包含共享模块、Android 和 iOS 平台模块 include ':shared', ':androidApp', ':iosApp'
-
多平台适配 :在 KMM 中,通常将跨平台逻辑放在
shared
模块,并通过include
声明其与平台模块的关联。
4.2 定义模块路径
-
调整模块路径:若模块不在默认路径下(如将 iOS 模块放在 ios 目录),需通过 project 函数指定路径。示例:
include ':shared', ':androidApp' // 指定 iOS 模块路径 project(':iosApp').projectDir = new File('ios/application')
4.3 配置插件和仓库
-
插件版本管理:在 KMM 中,需统一 Kotlin 插件版本以兼容多平台构建。示例:
pluginManagement { repositories { google() mavenCentral() gradlePluginPortal() } // 指定 Kotlin 和 Android 插件版本 plugins { id 'org.jetbrains.kotlin.multiplatform' version '1.9.20' id 'com.android.application' version '8.1.0' } }
4.4 管理依赖解析策略
-
统一依赖仓库:声明全局仓库地址(如 Maven Central、Google 仓库),确保所有模块使用相同的依赖源。示例:
dependencyResolutionManagement { repositories { google() mavenCentral() } }
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 文件的作用
文件名 | 平台 | 功能 |
---|---|---|
gradlew |
Unix/Linux/macOS | Shell 脚本,用于执行 Gradle 命令(如 ./gradlew build ) |
gradlew.bat |
Windows | 批处理脚本,功能同上(如 gradlew.bat build ) |
gradle/wrapper/ 目录 |
所有平台 | 包含 Wrapper 的核心文件(如 gradle-wrapper.jar 和 gradle-wrapper.properties ) |
5.3 核心文件解析
1)**gradle-wrapper.properties
**
位于 gradle/wrapper/gradle-wrapper.properties
,定义了 Gradle 的下载地址和版本:
# 指定使用的 Gradle 发行版类型(通常是 'bin' 或 'all')
distributionType=bin
# 指定 Gradle 版本(必须与项目兼容)
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
# 运行构建命令
./gradlew build
# 清理构建缓存
./gradlew clean
# 更新 Gradle 版本(修改 gradle-wrapper.properties 后)
./gradlew wrapper --gradle-version=8.5
2)Windows
# 运行构建命令
gradlew.bat build
# 清理构建缓存
gradlew.bat clean
5.5 为何需要提交这些文件到版本控制?
- 确保一致性:所有开发者使用相同的 Gradle 版本和配置。
- 简化协作:新成员无需手动安装或配置 Gradle,直接运行 Wrapper 即可。
5.6 常见问题
1)Q1:gradlew
权限被拒绝?
-
解决方法:赋予执行权限:
chmod +x gradlew
2)Q2:如何更新 Gradle 版本?
-
修改
gradle-wrapper.properties
中的distributionUrl
。 -
运行 Wrapper 任务以下载新版本:
./gradlew wrapper --gradle-version=8.5
3)Q3:gradlew
文件被误删怎么办?
- 恢复方法:重新生成 Wrapper;
》https://coderyuan.com/2021/05/28/KMM-2/