🚀KMP适配鸿蒙开发实战|从0到1搭建可运行工程
🔥 上一篇我们详解了KMP与鸿蒙整合的核心原理和适配方案,本文聚焦落地实操,从环境搭建、工程配置到代码编写、调试运行,手把手教你搭建一套能同时运行在鸿蒙/Android/iOS的KMP工程
📋 前置说明
本文是《KMP适配鸿蒙开发》系列第二篇,核心目标是帮你完成:
- ✅ 搭建兼容鸿蒙的KMP工程环境
- ✅ 配置鸿蒙自定义平台编译参数
- ✅ 编写跨平台共享代码+鸿蒙专属实现
- ✅ 鸿蒙工程集成KMP模块并调试运行
🔧 一、环境搭建:从0配置兼容环境
1.1 核心工具清单(必装)
| 工具 | 版本要求 | 作用说明 |
|---|---|---|
| JDK | 11+ | 鸿蒙/Android/KMP编译基础 |
| Android Studio | 2022.3 Giraffe+ | KMP工程开发+鸿蒙SDK配置+断点调试 |
| DevEco Studio | 4.0+(可选) | 鸿蒙UI预览+鸿蒙真机调试 |
| 鸿蒙SDK | API 9+(OpenHarmony 4.0+) | 鸿蒙平台核心依赖 |
| Kotlin插件 | 1.9.0+ | KMP编译核心插件,对鸿蒙适配更友好 |
| Gradle | 8.2+ | 工程构建工具,需与AGP版本匹配 |
1.2 鸿蒙SDK配置(关键步骤)
1.2.1 下载SDK
打开Android Studio → File > Settings > Appearance & Behavior > System Settings > HarmonyOS SDK → 勾选「SDK Platforms」下的API 9+版本(Stage模型)→ 点击「Apply」下载
1.2.2 配置环境变量
| 系统 | 配置步骤 |
|---|---|
| Windows | 右键「此电脑」→ 高级系统设置 → 环境变量 → 新建系统变量: 变量名:OHOS_SDK_HOME 变量值:D:\DevEcoStudio\SDK\ohos-sdk(实际SDK路径) |
| Mac/Linux | 编辑~/.bash_profile或~/.zshrc,添加: export OHOS_SDK_HOME=/Users/xxx/DevEcoStudio/SDK/ohos-sdk 执行source ~/.zshrc生效 |
1.2.3 验证配置
打开终端执行对应命令,确认路径正确输出:
bash
# Windows
echo %OHOS_SDK_HOME%
# Mac/Linux
echo $OHOS_SDK_HOME
1.3 Gradle全局配置
修改项目根目录 build.gradle.kts,配置兼容的插件和仓库:
kotlin
// 项目根目录 build.gradle.kts
buildscript {
repositories {
google()
mavenCentral()
// 华为鸿蒙官方Maven仓库
maven { url = uri("https://repo.huawei.com/repository/maven/") }
}
dependencies {
// AGP插件(需与AS版本匹配)
classpath("com.android.tools.build:gradle:8.2.0")
// KMP核心插件(1.9.20为稳定版)
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.20")
// 鸿蒙Gradle插件(可选,用于鸿蒙工程打包)
classpath("com.huawei.ohos:ohos-gradle-plugin:4.0.0.300")
}
}
allprojects {
repositories {
google()
mavenCentral()
maven { url = uri("https://repo.huawei.com/repository/maven/") }
// 鸿蒙开源仓库(补充依赖)
maven { url = uri("https://openharmony.gitee.io/ohpm/repository/") }
}
}
// 清理构建缓存任务(可选,解决依赖冲突)
tasks.register("clean", Delete::class) {
delete(rootProject.buildDir)
}
// 配置Gradle JVM版本(关键,避免编译异常)
tasks.withType<JavaCompile> {
sourceCompatibility = JavaVersion.VERSION_11.toString()
targetCompatibility = JavaVersion.VERSION_11.toString()
}
🛠️ 二、KMP工程核心配置(适配鸿蒙)
2.1 共享模块(shared)完整配置
修改 shared 模块的 build.gradle.kts,添加鸿蒙自定义平台配置(含详细注释):
kotlin
// shared模块 build.gradle.kts
plugins {
kotlin("multiplatform") version "1.9.20"
id("com.android.library")
}
// 全局变量:获取鸿蒙SDK路径(增加容错处理)
val ohosSdkHome = System.getenv("OHOS_SDK_HOME")
?: System.getProperty("OHOS_SDK_HOME")
?: throw GradleException("未配置OHOS_SDK_HOME环境变量!请参考文档配置")
// 校验鸿蒙SDK关键文件
val ohosSdkJar = File("$ohosSdkHome/platforms/ohos-9/ohos-sdk.jar")
if (!ohosSdkJar.exists()) {
throw GradleException("鸿蒙SDK文件缺失:${ohosSdkJar.absolutePath}\n请确认下载了API 9+版本的鸿蒙SDK")
}
kotlin {
// 1. 配置Android平台(基础)
androidTarget {
compilations.all {
kotlinOptions {
jvmTarget = "11" // 与鸿蒙JVM版本严格对齐
freeCompilerArgs = listOf("-Xopt-in=kotlin.RequiresOptIn")
}
}
}
// 2. 配置iOS平台(保留KMP跨端特性)
iosX64()
iosArm64()
iosSimulatorArm64()
// 3. 核心:创建鸿蒙自定义平台(基于JVM预设)
val harmonyTarget = targetFromPreset(jvmPreset, "harmony") {
compilations.all {
kotlinOptions {
jvmTarget = "11"
// 鸿蒙兼容的编译参数(关键)
freeCompilerArgs = listOf(
"-Xjvm-default=all", // 兼容默认方法实现
"-opt-in=kotlin.RequiresOptIn",
"-Xskip-metadata-version-check" // 跳过元数据版本检查,避免编译报错
)
}
// 配置鸿蒙编译类路径(必须)
compileClasspath += files(ohosSdkJar)
runtimeClasspath += files(ohosSdkJar)
// 排除Android冲突依赖
compileDependencyFiles = compileDependencyFiles.filter {
!it.name.contains("android") && !it.name.contains("androidx")
}
}
}
// 4. 源码集配置(核心)
sourceSets {
// 跨平台共享代码(核心业务逻辑)
val commonMain by getting {
dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib-common")
// 可选:Ktor网络库(跨平台网络请求)
implementation("io.ktor:ktor-client-core:2.3.5")
// 可选:Coroutines协程(跨平台异步)
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
// 可选:序列化库(跨平台数据解析)
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0")
}
}
// 跨平台测试代码
val commonTest by getting {
dependencies {
implementation(kotlin("test"))
implementation("io.mockk:mockk-common:1.13.8")
}
}
// Android专属代码
val androidMain by getting {
dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib")
implementation("io.ktor:ktor-client-android:2.3.5")
}
}
// iOS专属代码
val iosMain by creating {
dependsOn(commonMain)
dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib-ios")
implementation("io.ktor:ktor-client-ios:2.3.5")
}
}
// 🔥 鸿蒙专属代码(核心适配)
val harmonyMain by creating {
dependsOn(commonMain)
dependencies {
// 鸿蒙核心SDK依赖
implementation(files(ohosSdkJar))
// 鸿蒙Stage模型核心依赖
implementation("com.huawei.ohos:os:4.0.0.300")
implementation("com.huawei.ohos:agp:4.0.0.300")
// 鸿蒙网络库(对接Ktor)
implementation("com.huawei.ohos:network:4.0.0.300")
// 排除冲突依赖
configurations.all {
exclude(group = "com.android")
exclude(group = "androidx")
}
}
// 指定鸿蒙源码目录
kotlin.srcDir("src/harmonyMain/kotlin")
resources.srcDir("src/harmonyMain/resources")
}
}
}
// Android基础配置(兼容)
android {
namespace = "com.example.kmp_harmony"
compileSdk = 34
defaultConfig {
minSdk = 21
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
// 避免鸿蒙与Android资源冲突
sourceSets {
getByName("main") {
resources.exclude("**/harmony/*")
}
}
}
// 🌟 辅助任务:验证鸿蒙SDK可用性
tasks.register("checkOhosSdk") {
group = "verification"
description = "验证鸿蒙SDK配置是否正确"
doLast {
println("🔍 正在验证鸿蒙SDK配置...")
println(" OHOS_SDK_HOME: $ohosSdkHome")
println(" SDK Jar路径: ${ohosSdkJar.absolutePath}")
check(ohosSdkJar.exists()) {
"❌ 鸿蒙SDK缺失!路径:${ohosSdkJar.absolutePath},请检查OHOS_SDK_HOME配置"
}
println("✅ 鸿蒙SDK验证通过!版本:OpenHarmony 4.0+")
}
}
// 构建前先验证SDK
tasks.named("build").configure {
dependsOn("checkOhosSdk")
}
2.2 标准化源码目录结构
按KMP规范创建目录,重点新增鸿蒙专属目录(附目录作用说明):
shared/
├── src/
│ ├── commonMain/kotlin/ // 📝 跨平台共享业务逻辑(核心)
│ │ └── com/example/kmp_harmony/
│ │ ├── Platform.kt // 预期接口定义(平台能力抽象)
│ │ ├── SharedRepository.kt // 共享业务类(数据处理/逻辑封装)
│ │ ├── model/ // 数据模型(跨平台复用)
│ │ └── util/ // 通用工具类(字符串/日期等)
│ ├── androidMain/kotlin/ // 🤖 Android专属实现
│ │ └── com/example/kmp_harmony/
│ │ └── Platform.kt // Android平台实现
│ ├── iosMain/kotlin/ // 🍎 iOS专属实现
│ │ └── com/example/kmp_harmony/
│ │ └── Platform.kt // iOS平台实现
│ ├── harmonyMain/kotlin/ // 🪁 鸿蒙专属实现(核心适配)
│ │ └── com/example/kmp_harmony/
│ │ ├── Platform.kt // 鸿蒙平台实现
│ │ └── util/ // 鸿蒙专属工具类
│ ├── commonTest/kotlin/ // 🧪 跨平台测试代码
│ └── harmonyTest/kotlin/ // 🧪 鸿蒙平台测试代码
├── build.gradle.kts // KMP核心配置
└── proguard-rules.pro // 混淆规则(鸿蒙/Android通用)
✍️ 三、代码编写:跨平台+鸿蒙适配
3.1 跨平台共享代码(commonMain)
在commonMain中定义预期接口和共享业务逻辑(增加异常处理和注释):
kotlin
// commonMain/kotlin/com/example/kmp_harmony/Platform.kt
package com.example.kmp_harmony
/**
* 跨平台能力抽象接口
* 定义各平台需实现的基础能力,保证业务逻辑层无平台依赖
*/
expect class Platform {
/** 平台名称(含版本信息) */
val platformName: String
/**
* 显示提示框(适配各平台Toast/Alert)
* @param message 提示文本
* @param duration 显示时长:SHORT/ LONG
*/
fun showToast(message: String, duration: ToastDuration = ToastDuration.SHORT)
}
/**
* Toast显示时长枚举(跨平台统一)
*/
enum class ToastDuration {
SHORT, LONG
}
/**
* 共享业务仓库(100%跨平台复用)
* 封装核心业务逻辑,不包含任何平台相关代码
*/
class SharedRepository {
/**
* 获取平台信息
* @return 格式化的平台信息字符串
*/
fun getPlatformInfo(): String {
val platform = Platform()
return """
📱 当前运行平台:${platform.platformName}
🔧 KMP版本:1.9.20
🕒 构建时间:${System.currentTimeMillis()}
""".trimIndent()
}
/**
* 通用提示方法
* @param message 提示内容
*/
fun showTip(message: String) {
try {
Platform().showToast("💡 KMP提示:$message")
} catch (e: Exception) {
println("❌ 提示框显示失败:${e.message}")
}
}
/**
* 跨平台数据处理(示例:过滤+格式化+排序)
* @param data 原始数据列表
* @return 处理后的标准化数据
*/
fun processData(data: List<String>): List<String> {
return data.filter { it.isNotBlank() && it.length > 2 }
.map { it.trim().uppercase() }
.distinct()
.sorted()
}
}
3.2 鸿蒙专属实现(harmonyMain)
在harmonyMain中实现预期接口,增加异常处理和兼容性适配:
kotlin
// harmonyMain/kotlin/com/example/kmp_harmony/Platform.kt
package com.example.kmp_harmony
import com.huawei.ohos.abilityshell.ContextHolder
import com.huawei.ohos.agp.components.ToastDialog
import com.huawei.ohos.utils.zson.ZSONObject
/**
* 鸿蒙平台能力实现类
* 对接鸿蒙原生API,实现跨平台抽象接口
*/
actual class Platform {
// 鸿蒙平台标识(含详细版本信息)
actual val platformName: String by lazy {
try {
val osInfo = ZSONObject.stringToZSON(ContextHolder.getContext()
.getSystemProperties("hw_sc.build.os.version"))
"HarmonyOS ${osInfo.getString("display_version")} (Stage 模型 / API 9)"
} catch (e: Exception) {
"HarmonyOS 4.0 (Stage 模型)"
}
}
/**
* 实现鸿蒙Toast显示
* @param message 提示文本
* @param duration 显示时长
*/
actual fun showToast(message: String, duration: ToastDuration) {
try {
// 获取鸿蒙应用上下文(兼容不同运行环境)
val context = ContextHolder.getContext() ?: return
// 鸿蒙原生ToastDialog配置
val toast = ToastDialog(context).apply {
setText(message)
setAlignment(ToastDialog.Alignment.CENTER)
// 适配时长枚举
setDuration(
if (duration == ToastDuration.LONG)
ToastDialog.DURATION_LONG
else
ToastDialog.DURATION_SHORT
)
// 设置Toast样式(可选)
setBackgroundColor(0xCC000000.toInt())
setTextColor(0xFFFFFFFF.toInt())
}
toast.show()
} catch (e: Exception) {
println("❌ 鸿蒙Toast显示失败:${e.message}")
}
}
}
📱 四、鸿蒙工程集成KMP模块
4.1 创建鸿蒙Stage模型工程
- 打开DevEco Studio → 新建工程 → 选择「Empty Ability (Stage)」
- 配置工程信息:
- 项目名称:KMP_Harmony_Demo
- 包名:com.example.kmp_harmony(必须与KMP工程一致)
- SDK版本:API 9(OpenHarmony 4.0)
- 设备类型:Phone/Tablet
4.2 工程关联配置
- 将KMP工程的
shared模块复制到鸿蒙工程根目录 - 修改鸿蒙工程的
settings.gradle,引入KMP模块:
groovy
// 鸿蒙工程 settings.gradle
include ':app', ':shared'
project(':shared').projectDir = new File(settingsDir, '../shared') // 根据实际路径调整
4.3 引入KMP共享模块
修改鸿蒙工程app模块的 build.gradle:
groovy
// 鸿蒙工程 app/build.gradle
plugins {
id 'com.huawei.ohos.hap'
id 'com.huawei.ohos.deppack'
}
ohos {
compileSdkVersion 9
defaultConfig {
compatibilityVersion 9
vendor "example"
versionCode 1
versionName "1.0.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-ohos.txt'), 'proguard-rules.pro'
}
}
// 配置JVM版本(关键)
compileOptions {
sourceCompatibility = 11
targetCompatibility = 11
}
}
dependencies {
// 🔥 依赖KMP共享模块
implementation project(':shared')
// 鸿蒙基础依赖
implementation 'com.huawei.ohos:os:4.0.0.300'
implementation 'com.huawei.ohos:agp:4.0.0.300'
implementation 'com.huawei.ohos:common:4.0.0.300'
// 测试依赖
testImplementation 'junit:junit:4.13.2'
ohosTestImplementation 'com.huawei.ohos.testkit:runner:4.0.0.300'
}
4.4 鸿蒙UI布局配置
创建ability_main.xml布局文件(src/main/resources/base/layout/):
xml
<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:orientation="vertical"
ohos:padding="32vp">
<Text
ohos:id="$+id:text_info"
ohos:height="match_content"
ohos:width="match_parent"
ohos:text="加载中..."
ohos:text_size="18fp"
ohos:margin_bottom="24vp"/>
<Button
ohos:id="$+id:btn_click"
ohos:height="match_content"
ohos:width="match_parent"
ohos:text="点击测试KMP"
ohos:text_size="16fp"
ohos:background_element="$graphic:button_background"/>
<Text
ohos:id="$+id:text_result"
ohos:height="match_content"
ohos:width="match_parent"
ohos:text="数据处理结果:"
ohos:text_size="16fp"
ohos:margin_top="24vp"/>
</DirectionalLayout>
4.5 鸿蒙页面调用KMP代码
修改鸿蒙MainAbilitySlice.kt,完善功能并增加异常处理:
kotlin
// 鸿蒙 MainAbilitySlice.kt
package com.example.kmp_harmony
import com.huawei.ohos.aafwk.ability.AbilitySlice
import com.huawei.ohos.aafwk.content.Intent
import com.huawei.ohos.agp.components.Button
import com.huawei.ohos.agp.components.Text
import com.huawei.ohos.utils.zson.ZSONArray
class MainAbilitySlice : AbilitySlice() {
private lateinit var repository: SharedRepository
override fun onStart(intent: Intent?) {
super.onStart(intent)
super.setUIContent(ResourceTable.Layout_ability_main)
// 初始化KMP共享仓库
repository = SharedRepository()
initView()
loadPlatformInfo()
}
/**
* 初始化UI组件
*/
private fun initView() {
// 点击按钮测试KMP功能
val btn = findComponentById<Button>(ResourceTable.Id_btn_click)
btn.setClickedListener {
testKmpFunction()
}
}
/**
* 加载平台信息
*/
private fun loadPlatformInfo() {
try {
val infoText = findComponentById<Text>(ResourceTable.Id_text_info)
infoText.text = repository.getPlatformInfo()
} catch (e: Exception) {
println("❌ 加载平台信息失败:${e.message}")
findComponentById<Text>(ResourceTable.Id_text_info).text = "加载失败:${e.message}"
}
}
/**
* 测试KMP核心功能
*/
private fun testKmpFunction() {
try {
// 1. 显示提示
repository.showTip("鸿蒙适配KMP成功!🚀")
// 2. 测试数据处理
val testData = listOf("kmp", "", "harmony", "android", "ios", "test")
val processedData = repository.processData(testData)
// 3. 显示处理结果
val resultText = findComponentById<Text>(ResourceTable.Id_text_result)
resultText.text = "数据处理结果:${processedData.joinToString(", ")}"
// 4. 打印日志
println("📊 KMP数据处理结果:${ZSONArray(processedData).toString()}")
} catch (e: Exception) {
repository.showToast("❌ 测试失败:${e.message}", ToastDuration.LONG)
println("❌ KMP功能测试失败:${e.message}")
}
}
}
🐞 五、调试运行与问题排查
5.1 标准运行流程
否
是
否
是
执行checkOhosSdk任务
SDK验证通过?
检查OHOS_SDK_HOME配置
编译shared模块
同步鸿蒙工程依赖
启动鸿蒙模拟器/连接真机
运行鸿蒙工程
运行成功?
查看日志排查问题
测试KMP功能
5.2 常见问题解决方案(新增场景)
| 问题现象 | 原因分析 | 解决方案 |
|---|---|---|
| ohos-sdk.jar找不到 | OHOS_SDK_HOME配置错误 | 检查环境变量,确保路径指向鸿蒙SDK根目录 |
| 字节码版本冲突 | JVM Target不一致 | 统一设置为11(KMP/Android/鸿蒙) |
| 鸿蒙Toast不显示 | 上下文获取失败 | 使用ContextHolder.getContext()替代Activity上下文 |
| 依赖冲突 | 鸿蒙与Android依赖重复 | 在KMP中用exclude排除冲突依赖 |
| 编译提示元数据版本不兼容 | Kotlin版本与鸿蒙SDK不匹配 | 添加-Xskip-metadata-version-check编译参数 |
| 找不到Platform类 | 源码集配置错误 | 确认harmonyMain依赖commonMain且包名一致 |
| 鸿蒙工程无法引入shared模块 | settings.gradle配置错误 | 检查模块路径是否正确,确保include ':shared' |
5.3 高级调试技巧
-
断点调试 :
在Android Studio中打开KMP工程,给
commonMain的SharedRepository打断点 → 运行鸿蒙工程 → 触发对应逻辑即可调试 -
日志过滤 :
在DevEco Studio的Logcat面板,添加过滤条件:
tag:KMP_Harmony或package:com.example.kmp_harmony -
编译日志查看 :
执行
./gradlew build --info(Mac/Linux)或gradlew build --info(Windows),查看详细编译日志 -
依赖树分析 :
执行
./gradlew :shared:dependencies,查看依赖树,排查冲突依赖
📌 六、核心总结
6.1 关键要点
- KMP适配鸿蒙的核心是基于JVM预设创建自定义平台 ,通过
expect/actual机制对接鸿蒙API,实现业务逻辑层100%复用; - 工程配置的核心是正确配置
OHOS_SDK_HOME环境变量,保证鸿蒙SDK依赖路径正确,同时统一JVM Target版本为11; - 开发时需严格隔离平台相关代码,共享层只保留纯Kotlin逻辑,平台层仅实现必要的原生API对接。
6.2 性能优化建议(新增)
- 鸿蒙端使用
lazy初始化减少内存占用; - 共享层数据处理避免频繁创建对象,使用不可变集合;
- 网络请求在鸿蒙端使用协程调度,避免主线程阻塞;
- 编译时开启R8混淆,减小APK/HAP体积。
6.3 避坑指南
- ❌ 不要尝试复用Compose UI到鸿蒙(暂不兼容);
- ❌ 避免直接使用鸿蒙私有API,优先选择OpenHarmony开源API;
- ❌ 不要在共享层引入任何平台相关依赖(如Android的androidx、鸿蒙的ohos包);
- ✅ 始终使用Stage模型开发鸿蒙应用(FA模型已淘汰);
- ✅ 对平台API调用增加异常处理,保证跨平台稳定性。
✨ 技术交流:如果本文对你有帮助,欢迎点赞+收藏+评论,也可关注博主获取《KMP适配鸿蒙》系列后续内容(第三篇:高级特性与性能优化)~
📚 参考资料:
- KMP官方文档:Kotlin Multiplatform
- 鸿蒙Stage模型开发指南:HarmonyOS Stage模型开发概述
- OpenHarmony SDK下载:OpenHarmony 快速入门
- Kotlin编译参数文档:Kotlin compiler options
欢迎加入开源鸿蒙跨平台社区,https://openharmonycrossplatform.csdn.net