什么是KMM?
在开始使用 KMM 之前,您需要了解 Kotlin。KMM 全称 Kotlin Multiplatform Mobile,是一个用于跨平台移动开发的 SDK。相比于其他跨平台框架,KMM 采用原生 UI 加逻辑共享的理念,通过封装成 Android 的 AAR 和 iOS 的 Framework,供视图层调用。
KMM 利用 Kotlin 的多平台功能,允许您使用 Kotlin 语言和技术栈开发一套可在多平台之间共享的代码库,从而构建统一的代码逻辑,无需为每个平台单独实现。
环境工具准备
为了开始使用 KMM,您需要安装以下工具:
- Java JDK 版本 11
- Ruby 和 Bundler
- Android Studio 版本 4.2 或更高
- Xcode 版本 11.3 或更高
- Xcode 命令行开发者工具
- Android Studio 的 Kotlin Multiplatform Mobile 插件。安装方法:在 Android Studio 中,选择 Preferences > Plugins,然后在 Marketplace 中搜索并安装该插件。
准备就绪后,即可创建您的第一个 KMM 项目。
创建第一个 KMM 项目
创建 KMM 项目的步骤如下:
- 打开 Android Studio,点击新建项目。
- 在项目模板中,选择“KMM 应用程序”,然后点击下一步。
- 输入项目名称、最低 SDK 版本,点击下一步。
- 更改 Android 和 iOS 的应用程序名称,可选择为共享模块添加示例测试,然后点击下一步。
- 对于 iOS 应用程序,可以在 Regular Framework 或 CocoaPods 依赖管理器之间选择。如果使用 CocoaPods,需要已安装 Ruby。
- 点击下一步,等待 Gradle 完成项目设置。
项目加载成功后,您将看到以下模块:androidApp、iosApp 和 shared。在配置中选择 androidApp 或 iOSApp 运行到相应模拟器。通过 Android Studio 可以运行 iOS 应用,KMM 会利用 Gradle 插件自动调用 Xcode 构建并启动模拟器。
注意:使用 KMM 插件建立的工程默认使用 Kotlin(.kts 文件)进行 Gradle 配置,且 iOS 工程默认使用 Swift UI。如果需要传统 iOS UI 开发,需要以集成形式新建 KMM 模块。
KMM工程结构
KMM 插件建立的工程目录结构如下:
├── androidApp # 实际 Android APP Module
├── build.gradle.kts # 工程根 Gradle 配置
├── gradle
├── gradle.properties
├── gradlew
├── gradlew.bat
├── iosApp # 实际的 iOS 工程根目录
├── local.properties
├── settings.gradle.kts
└── shared # KMM 模块代码目录
├── build.gradle.kts # KMM 模块 Gradle 配置
└── src
├── androidMain # Android 差异化代码
├── commonMain # 共享模块 API 代码
├── iosMain # iOS 差异化代码
└── nativeInterop # 用于与 C/C++ 代码交互的配置
androidApp 和 iosApp 是平台工程模块,shared 是共享逻辑模块。根目录的 settings.gradle.kts 只包含了 androidApp 和 shared,因为 iOS 项目是 Xcode 项目,不通过 Gradle 连接,而是将 shared 模块打包成 Framework 使用。
特定于平台的API和实现
共享代码的目标是让同一份代码能在 Android 和 iOS 上运行。代码分为平台无关部分和平台相关部分。平台无关代码如算法逻辑,不涉及系统 API 访问;平台相关代码则在 AndroidApp 和 iOSApp 模块中实现。
KMM 使用 expect/actual 机制解决平台相关性问题。expect 声明期望的接口,actual 在各个平台上实现。
shared模块的实现形式
在 shared 模块的 commonMain 中,Greeting 类使用 platform.name:
class Greeting {
private val platform: Platform = getPlatform()
fun greet(): String {
return "Hello, ${platform.name}!"
}
}
interface Platform {
val name: String
}
expect fun getPlatform(): Platform
Android 实现:
class AndroidPlatform : Platform {
override val name: String = "Android ${android.os.Build.VERSION.SDK_INT}"
}
actual fun getPlatform(): Platform = AndroidPlatform()
iOS 实现:
import platform.UIKit.UIDevice
class IOSPlatform: Platform {
override val name: String = UIDevice.currentDevice.systemName() + " " + UIDevice.currentDevice.systemVersion
}
actual fun getPlatform(): Platform = IOSPlatform()
Android 调用:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyApplicationTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colors.background
) {
GreetingView(Greeting().greet())
}
}
}
}
}
@Composable
fun GreetingView(text: String) {
Text(text = text)
}
iOS 调用:
import SwiftUI
import shared
struct ContentView: View {
let greet = Greeting().greet()
var body: some View {
Text(greet)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
KMM vs Flutter vs RN
KMM 与 Flutter 和 React Native 在跨平台方法上不同。KMM 使用 Kotlin 编译器生成平台特定字节码,适合逻辑代码共享,如模型层、网络请求等;而 Flutter 适合 UI 构建,因为它统一了渲染引擎。
- 体积:Flutter 和 RN 需要内置引擎,增加包体积;KMM 生成原生依赖,对体积影响较小。
- 技术栈:Flutter 使用 Dart,KMM 使用 Kotlin,RN 使用 JavaScript。
- 适用场景:Flutter 适合界面构建;KMM 适合非 UI 逻辑,因为 UI 组件差异大,共享意义有限。
KMM 通过 Kotlin Multiplatform 技术,为多种平台创建应用程序并重用代码,保留原生优势。
Kotlin Multiplatform
Kotlin Multiplatform 支持 iOS、Android、macOS、Windows、Linux 等平台。它包括:
- Kotlin Stdlib(JVM)
- Kotlin Native(调用平台原生 API)
- Kotlin JS(用于 Web 开发)
Compose Multiplatform 是 JetBrains 开发的声明式 UI 框架,实现在 Android 和 iOS 之间共享 UI。
Kotlin Multiplatform Wizard
可以使用 Kotlin Multiplatform Wizard 创建跨平台应用程序,选择平台和 UI 框架(如 Compose Multiplatform),支持服务器和桌面项目。