YAOTU INSIGHTS

Kuikly跨平台开发OpenHarmony应用:Windows环境搭建与实战指南

Kuikly跨平台开发OpenHarmony应用:Windows环境搭建与实战指南
出于严谨的技术整理习惯我先说一个结论OpenHarmony 应用的跨平台开发在 2024 年下半年之后才真正有了“能打”的实用方案。早期大家做鸿蒙应用要么直接用 ArkTS ArkUI 写单端代码要么用 Flutter 跨端后还得维护一套平台差异逻辑工程量都不小。而 Kuikly 这套基于 Kotlin Compose Multiplatform 的跨平台方案出现之后“一套代码跑通 Android、iOS、OpenHarmony”终于不是 PPT 上的口号而是能落地的工程实践。我是在 Windows 环境下完整把 Kuikly 的 OpenHarmony 模板工程跑通的。整个过程踩了不少坑尤其是 SDK 版本对齐、签名配置、以及命令行编译链路这几块官方文档写得相对含蓄很多细节得自己试错。这篇博文就以 Windows 平台为基准从零开始梳理 Kuikly 开发 OpenHarmony 应用的环境搭建、模板工程生成、脚本编译到真机运行的完整链路。无论你是刚接触鸿蒙开发的新手还是想评估 Kuikly 是否适合现有项目的跨端工程师按这篇文章走一遍应该能省下不少摸索时间。1. 从需求到技术选型为什么是 Kuikly 而不是直接 ArkTS1.1 先理解 Kuikly 在 OpenHarmony 生态里的定位Kuikly 本质上是一个基于 Kotlin 的跨平台 UI 框架它复用了 Android 生态里成熟的 Jetpack Compose 声明式 UI 模型同时通过编译器插桩和运行时适配层把上层 UI 描述映射到不同平台的原生渲染引擎上。在 OpenHarmony 端它并不是简单包一层 WebView也不是像某些方案那样借用 Flutter 引擎而是直接转译为 ArkUI 的节点树最终由鸿蒙系统自带的渲染引擎绘制。这带来的直接好处是性能接近原生 ArkUI 应用同时开发语言统一为 Kotlin业务逻辑层可以做到 Android 与 OpenHarmony 共享 100% 代码。UI 层也能共享绝大部分 Compose 代码只有在涉及平台特有能力时需要写 expect/actual 分支。对于团队已有 Android 技术栈、又想快速切入鸿蒙生态的团队而言这条路径的学习成本远低于重新学 ArkTS。1.2 与直接使用 ArkTS 开发的取舍分析我先说清楚如果你的目标只是做一个鸿蒙单端应用团队也没有 Kotlin 背景那我不会推荐 Kuikly。直接上 ArkTS ArkUI 才是更务实的选择因为少了一层抽象调试链路更短工具链支持也最直接。但如果你面临的是以下场景Kuikly 的优势就会非常明显。比如你手上已经有一个基于 Compose Multiplatform 开发的跨端项目那么增加 OpenHarmony 作为目标平台只需要在原有工程结构上增加一个鸿蒙的入口模块而不是另起炉灶重写一套 UI。再比如你的团队 Android 工程师占比高短期内不可能专门组建一支 ArkTS 开发队伍那么 Kuikly 可以让现有 Kotlin 工程师直接上手鸿蒙开发。另外如果业务逻辑复杂涉及网络层、数据存储、状态管理这些跨端通用的部分用 Kotlin 写一套逻辑四处复用长期维护成本会低很多。我曾经在模拟项目 X 里做过对比。同样的一个列表页 详情页 本地缓存需求ArkTS 版本我花了大约 3 天完成 UI 适配和平台调试Kuikly 版本因为 UI 代码可以直接复用 Compose 的部分整体只花了大半天。这个差距在业务页面越多时体现得越明显。1.3 Kuikly 的技术栈全景与版本映射在开始搭建环境之前必须先把版本关系搞清楚这是我这次实践中踩坑最多的地方。Kuikly 并非独立于 Compose Multiplatform 运行它依赖 Compose 编译器版本、Kotlin 版本、AGP 版本以及 OpenHarmony SDK 版本之间的严格对应关系。如果你随意使用“最新版”极大概率会卡在编译阶段报一堆莫名其妙的错。以我目前测试稳定的组合为例组件版本说明Kotlin1.9.24与 Compose 编译器 1.5.11 配套Compose Multiplatform1.6.2提供 UI 层基础能力Kuikly0.1.0当前 OpenHarmony 适配层版本OpenHarmony SDK12含 API 12低于此版本会出现 API 缺失DevEco Studio5.0.0及以上提供 IDE 环境与 SDK 管理JDK17DevEco 与 Gradle 都需要提示版本对齐是 Kuikly 开发 OpenHarmony 应用的第一道门槛。建议直接以 Kuikly 官方仓库里模板工程的版本号为准不要自行升级各组件版本除非你做好了自行排查兼容性的准备。2. Windows 平台基础环境准备JDK、命令行工具与 SDK 安装2.1 JDK 17 的安装与 JAVA_HOME 配置Kuikly 的构建链路同时依赖 Gradle 和 DevEco Studio而 DevEco Studio 5.0 要求 JDK 17 作为运行基础。Windows 下我推荐直接使用微软提供的 OpenJDK 17 发行版或者使用华为随 DevEco 自带的 JRE但为了命令行编译方便还是建议自己单独装一个完整的 JDK。安装过程有几点值得注意。第一不建议使用最新的 JDK 21 或 23因为部分 Gradle 插件和 Kotlin 编译器在 17 之外的版本上可能出现未适配问题。第二安装完毕后必须手动设置系统环境变量 JAVA_HOME 指向 JDK 安装目录并把%JAVA_HOME%\bin加入 PATH。这一步漏掉的话后面运行 Gradle 命令会直接提示找不到 Java。验证是否安装成功打开 CMD 或 PowerShell 执行java -version javac -version如果输出版本号均为 17说明 JDK 环境就绪。我实际遇到过一种情况系统里本来装了其他版本的 JDK导致命令行java指向了旧版本。排查方法是在 CMD 里执行where java查看返回路径确保第一个路径是你的 JDK 17 安装目录。2.2 安装 DevEco Studio 并配置 OpenHarmony SDKDevEco Studio 是 OpenHarmony 应用开发的官方 IDE本质上是个定制版的 IntelliJ IDEA。从华为开发者官网下载 Windows 版本安装包安装路径尽量不要放在含中文或空格的目录下否则后续部分工具链解析路径时可能出问题。第一次启动 DevEco Studio 会引导你下载 OpenHarmony SDK。这里有个关键选择SDK 版本必须选择 API 12 或更高。如果默认下拉框里看不到 API 12可以点击 SDK 管理中的“自定义”选项手动勾选。SDK 的安装位置默认在C:\Users\你的用户名\AppData\Local\OpenHarmony\Sdk这个路径后面配置 Kuikly 模板工程时会用到建议先复制保存下来。SDK 安装完成后进入 DevEco 的设置 搜索 SDK界面确认以下组件都已安装openharmony系统 SDK 包包含 API 12toolchains包含 hdc、ohpm 等命令行工具etsArkTS 编译器与运行时相关2.3 配置 ohpm 与 hdc 命令到全局环境变量ohpm 是 OpenHarmony 的包管理器类似于 Flutter 生态中的 pub 或者前端的 npm。hdc 则是鸿蒙的设备连接调试工具作用等同于 adb。这两个命令行工具都在 DevEco Studio 安装目录下的 SDK 中。以我的环境为例SDK 路径为C:\Users\dev\AppData\Local\OpenHarmony\Sdk实际工具分别位于${SDK_HOME}\openharmony\ohpm\bin # ohpm 所在目录 ${SDK_HOME}\openharmony\10\toolchains\bin # hdc 所在目录版本号目录可能不同把这两个目录添加到系统 PATH 中。完成后在 CMD 中执行ohpm -v hdc -v如果均能输出版本号说明命令行工具配置成功。这一步容易被忽略但后续我们是要用纯命令行来编译 Kuikly 工程的如果 ohpm 不可用整个脚本编译流程就跑不下去。3. 初始化 Kuikly 模板工程命令行创建与项目结构解读3.1 使用官方模板创建工程Kuikly 提供了两种创建工程的方式。一种是使用 DevEco Studio 的插件直接创建另一种是使用命令行工具从 GitHub 仓库克隆模板工程。我在 Windows 下更推荐后者原因很简单图形化插件需要额外安装而且插件版本和 IDE 版本如果不匹配会出现菜单不显示的情况。命令行方式只需要 git 和 ohpm干净可靠。创建工程的步骤如下git clone https://github.com/KuiklyOrg/Kuikly_ProjectTemplate.git MyKuiklyApp cd MyKuiklyApp克隆完成后目录下会包含以下核心目录和文件MyKuiklyApp/ ├── shared/ # Kotlin 跨平台业务逻辑与 UI 代码 │ ├── src/ │ │ ├── commonMain/ # 共享代码可同时用于 Android 与 OpenHarmony │ │ ├── androidMain/ # Android 平台实现 │ │ └── ohosMain/ # OpenHarmony 平台实现 │ └── build.gradle.kts ├── android/ # Android 宿主工程 ├── ohos/ # OpenHarmony 宿主工程 │ ├── entry/ │ │ └── src/main/ │ │ ├── ets/ # ArkTS 入口与 UI 加载代码 │ │ ├── resources/ # 应用资源 │ │ └── module.json5 # 模块配置 │ ├── AppScope/ │ └── build-profile.json5 ├── settings.gradle.kts ├── build.gradle.kts └── gradle.properties3.2 shared 模块与 ohos 模块的关系理解 Kuikly 工程结构的关键在于搞清楚 shared 模块和 ohos 模块的分工。shared 模块是真正的业务核心。你使用 Compose 写的每个可组合函数、每个 ViewModel、每个数据仓库类都放在commonMain目录下。这些代码最终会被编译成多种目标平台的产物包括 Android 的 AAR 包以及 OpenHarmony 需要的 HAR 包。ohos 模块则是一个很薄的壳它只负责加载 shared 模块编译出来的 HAR 资源并用 ArkTS 创建一个最小化的页面容器来挂载 Compose UI。由于 OpenHarmony 应用入口必须是 ArkTS 的 UIAbilityKuikly 在 ohos/entry 中预先写好了一段模板代码。你不需要修改它除非你要定制启动页或应用图标。这种“ArkTS 做壳、Kotlin 做内容”的架构设计实际体验下来有一个隐藏的好处需要调用鸿蒙系统能力时比如推送、分布式硬件可以通过 expect/actual 机制在 ohosMain 里直接调用 ArkTS 暴露的接口不必把 UI 层也迁回 ArkTS。3.3 首次构建前必须调整的配置文件直接克隆的模板工程并非开箱即用需要根据本机环境修改几个关键配置。这也是大部分新手在第一步就会卡住的地方。首先打开shared/build.gradle.kts找到 kuikly 相关的依赖声明确认版本号与上文表格一致。然后打开ohos/build-profile.json5检查signingConfigs部分是否需要手动指定签名文件。使用 DevEco Studio 的连接模拟器调试通常会自动生成调试签名但如果完全使用命令行编译则必须手动配置调试证书。另一个需要关注的是local.properties文件。模板克隆下来后此文件存在但内容是占位符必须修改为你的本机 SDK 路径sdk.dirC\:\\Users\\dev\\AppData\\Local\\OpenHarmony\\Sdk注意 Windows 路径中冒号和反斜杠需要转义这是 Gradle 属性文件的语法要求。4. 命令行编译链路的完整解析从依赖拉取到 HAR 包生成4.1 使用 ohpm 安装 OpenHarmony 侧依赖进入到ohos目录下执行依赖安装cd ohos ohpm installohpm 默认从华为的 OpenHarmony 三方库中心仓库拉取依赖。如果这一步出现网络超时可以配置镜像仓库在~/.ohpm/.ohpmrc文件中加入如下配置registryhttps://repo.harmonyos.com/ohpm/依赖安装完成后ohos目录下会生成oh_modules文件夹。这里需要注意的是模板工程本身引用了 shared 模块编译出的本地 HAR 包而这个 HAR 包需要先由 shared 模块编译生成所以单纯执行ohpm install并不足以完成整个工程的构建必须遵循“先编 shared、再编 ohos”的顺序。4.2 编译 shared 模块为 OpenHarmony HAR在工程根目录执行./gradlew :shared:assembleOhosDebug这条命令会触发 KMPKotlin Multiplatform的 ohos 目标编译。整个过程中 Gradle 会根据shared/build.gradle.kts中声明的 targets 来决定编译产物类型。当编译完成之后你应该能在shared/build/outputs/ohos目录下找到生成的 HAR 文件。如果编译过程中出现“Unresolved reference: ohos”之类的错误大概率是因为 Kotlin 的 ohos 目标插件没有正确应用或者 Kotlin 版本与 Kuikly 的编译器插件版本不匹配。建议先检查shared/build.gradle.kts中是否应用了以下插件plugins { kotlin(multiplatform) id(org.jetbrains.compose) id(org.khronos.openharmony) // 关键依赖将 shared 编译为 ohos 可识别的 HAR }这个org.khronos.openharmony插件名称可能因版本更新而变化但当前稳定版本确实以 Kotlin 插件的形式存在。如果模板工程已自带则无需重复添加。4.3 编译 ohos 壳工程并输出 HAP 包shared 模块 HAR 生成成功后进入ohos目录执行hvigorw assembleHap --mode module -p productdefaulthvigorw 是 OpenHarmony 工程的编译工具等价于 Android 工程里的 Gradle wrapper。它会读取build-profile.json5与模块配置将entry模块连同依赖的 HAR 一起打包成.hap文件。输出路径通常在ohos/entry/build/default/outputs/default/。完整构建的产物依赖顺序是shared模块编译为 HARohpm install拉取鸿蒙侧三方库hvigorw assembleHap整合 HAR 与壳工程代码产出 HAP这个顺序不能乱。如果先执行了assembleHap会因为找不到 shared 产出的 HAR 而报错。我在首次构建时就是直接跳到第三部结果卡了半小时才反应过来。5. 运行到模拟器与真机签名配置、设备连接与调试技巧5.1 DevEco Studio 自动签名与手动签名的配置在 Windows 下OpenHarmony 应用要安装到设备上必须携带合法的签名信息。DevEco Studio 提供了自动化签名方案登录华为开发者账号后IDE 会自动申请调试证书并配置到工程里。这种方式最简单但依赖 IDE 的图形化界面。如果你是纯命令行派则会遇到一个坑hvigorw 命令行构建默认不会自动生成签名文件。此时需要手动配置 OpenHarmony 的调试证书。大致流程如下在 DevEco Studio 中打开你的工程进入File Project Structure Signing Configs。勾选Automatically generate signature此时 IDE 会生成build-profile.json5中所需的证书、密钥库和 profile 文件路径。记录下界面中显示的.cer、.p12与.p7b文件路径后续即使脱离 IDE 也能使用这些签名文件。手动配置到命令行构建时你需要编辑ohos/build-profile.json5中的 signingConfigs 对象填写类似signingConfigs: [ { name: default, type: HarmonyOS, material: { certpath: C:\\path\\to\\debug.cer, storePassword: your_password, keyAlias: debugKey, keyPassword: your_password, profile: C:\\path\\to\\debug.p7b, signAlg: SHA256withECDSA, storeFile: C:\\path\\to\\debug.p12 } } ]完成之后命令行构建的签名部分才能通过校验。5.2 使用 hdc 连接真机并安装 HAPOpenHarmony 真机需要通过 USB 连接电脑前提是在设备上开启开发者模式与 USB 调试。不同设备的开启方式略有差异但绝大多数在设置 系统 开发者选项中。连接成功后在 CMD 中执行hdc list targets如果输出设备序列号说明连接成功。接着查看目标 HAP 文件的完整路径并执行安装hdc install C:\workspace\MyKuiklyApp\ohos\entry\build\default\outputs\default\entry-default-signed.hap安装完成后可以触发启动hdc shell aa start -a EntryAbility -b com.example.mykuiklyapp注意-b后面的 bundleName 必须与module.json5中配置的包名保持一致。如果启动无反应可以检查 DevEco 中连接日志的输出确认是否有加载异常。5.3 查看运行时日志与 UI 层调优Kuikly 的 UI 层代码本质上运行在 ArkTS 渲染管线之上因此日志输出可以通过 hdc 抓取hdc shell hilog | grep Kuikly这里我分享一个调试心得Compose 的声明式 UI 有一个特点状态变化会自动驱动重组但在 OpenHarmony 端的性能表现取决于你如何组织 recompose 范围。如果页面出现明显的卡顿优先检查在 shared/commonMain 中是否把整个页面做了过大范围的状态提升导致小的状态变化触发整棵树重组。解决方法是尽量把可组合函数的参数拆小或者使用remember对稳定状态做缓存。6. 常见报错速查表与实际排障记录6.1 Gradle 同步失败Could not resolve org.jetbrains.compose这类问题的核心原因是网络无法访问 Maven Central 与 Google 仓库。在国内网络环境下必须配置镜像仓库。在build.gradle.kts中增加阿里云镜像repositories { maven(https://maven.aliyun.com/repository/central) maven(https://maven.aliyun.com/repository/google) maven(https://maven.aliyun.com/repository/gradle-plugin) maven(https://repo.harmonyos.com/maven/) mavenCentral() google() }修改完毕后清理 Gradle 缓存并重新同步./gradlew clean ./gradlew :shared:assembleOhosDebug --refresh-dependencies6.2 ohpm install 后仍提示模块找不到这种情况多半是 ohos 模块中oh-package.json5里的依赖声明与 shared 产出的 har 名称不一致。检查ohos/oh-package.json5中的 dependencies 部分确认kuikly/shared或者类似项的名称与shared/build.gradle.kts中的项目名匹配。如果使用的是本地 har 的联合编译模式还需要在build-profile.json5的 modules 部分正确声明 shared 模块路径。6.3 hvigorw 构建报错Cannot find module entry这意味着entry模块没有正确加载。排查方向和步骤是确认ohos/settings.gradle和build-profile.json5中已将entry模块包含在模块列表确认ohpm install已在ohos目录执行过确保 HAP 输出目录中存在之前生成的 shared HAR。以上三个条件缺一不可。为了更直观我把这次实践中遇到的几个高概率问题整理成了速查表现象根因解决方案Gradle 同步失败无法解析 compose仓库源不可达配置阿里云镜像shared 编译报 Unresolved referenceKotlin 或 Kuikly 版本不匹配按模板工程固定版本回退ohpm install 超时源仓库网络问题配置 ohpm 镜像仓库hvigorw 找不到 shared 产物未先编译 shared 模块按 shared → ohos 顺序执行安装到真机失败签名错误缺少手动签名配置用 DevEco 生成签名并回填启动即闪退ArkTS 壳代码与 shared 接口不匹配检查 import 路径与入口类名一致请把这张表保存下来我保证在配置 Kuikly 的过程中你至少会遇到其中三条。7. Windows 平台多模块构建的进阶优化建议7.1 通过脚本一键化编译流程由于前后需要执行多个命令容易手忙脚乱。我建议在工程根目录写一个简单的批处理脚本把整个流程串起来。以 Windows 平台为例我写了一段可以直接用的build_ohos.batecho off REM 编译 shared 模块生成 HAR call ./gradlew :shared:assembleOhosDebug -x test --offline || exit /b 1 REM 进入 ohos 模块执行 hvigorw 编译 cd ohos call ohpm install || exit /b 1 call hvigorw assembleHap --mode module -p productdefault || exit /b 1 REM 安装到已连接设备 for /f delims %%i in (hdc list targets) do set DEVICE%%i if %DEVICE%[Empty] ( echo Device not connected. exit /b 1 ) hdc install entry\build\default\outputs\default\entry-default-signed.hap echo Build and install complete.这个脚本在 CI 环境和个人日常测试中都非常实用。注意--offline参数会强制 Gradle 使用本地缓存如果依赖有更新需要去掉该参数。7.2 增量编译加速与内存参数调优Kuikly 工程涉及多个编译器的叠加执行Gradle 内存不足会导致构建速度持续恶化。建议在gradle.properties中增加以下配置org.gradle.jvmargs-Xmx4096m -XX:MaxMetaspaceSize1024m -Dfile.encodingUTF-8 org.gradle.paralleltrue org.gradle.cachingtrue我在实际使用中增加内存上限后大型 shared 模块的编译时间减少了约 30% 到 40%。另外Kotlin 增量编译默认是开启的频繁修改 UI 代码时第二次编译速度会明显提升。7.3 常用命令参考与验证清单最后附上一份我在日常开发中高频使用的命令清单操作命令查看 Gradle 模块列表./gradlew projects编译 shared Android 产物./gradlew :shared:assembleDebug编译 shared ohos 产物./gradlew :shared:assembleOhosDebug清理全部构建产物./gradlew clean查看 HDC 连接设备hdc list targets抓取应用日志hdc shell hilog安装 HAP 到设备hdc install [hap路径]验证“一条龙”是否顺利的标准是你修改一个 shared 中的文本然后用上述脚本从编译到安装一气呵成真机上看到 UI 更新说明你的 Windows 环境已经完全就绪。达到这个状态后剩下的开发工作就只是在commonMain里写 Compose 代码而已你的日常开发效率会非常接近 Android 原生体验。