KMP / CMP 鸿蒙版本 Beta 发布,他有什么特别之处?

华为官方适配的 KMP/CMP 鸿蒙适配版本终于出来了,这个版本真的拖了好久了,虽然之前也有腾讯维护的 ovComposeKuikly 版本,但是现在华为官方的社区版本终于出来,也算是给了 KMP/CMP 鸿蒙官方适配的名分

当然,他实际上和 ovComposeKuikly 版本也是密不可分。

事实上 KMP/CMP 适配鸿蒙的门槛还是相当高的,它需要把鸿蒙当作 Kotlin/Native 的新 Target 实现,这次的实现路线需要大量的 KN 和 LLVM 适配,然后 Kotlin 会直接编译成鸿蒙 ELF 二进制,再用 NAPI / CAPI 和 ArkTS / ArkUI 协作完成渲染。

Kotlin/Native 用 KonanTarget 描述"我要为谁出二进制",每个 Target 一般有三要素:family、architecture、triple。

当然,这套代码 Kotlin/Native 核心实现来自腾讯 KuiklyBase 体系,CMP UI 那边的统一渲染也是来自腾讯 ovCompose ,所以项目里你可以看到不少 // region Tencent Cod 这样的代码,grep "// region Tencent Code" -r 就能列出对应改动。

KMP 鸿蒙

KMP 适配鸿蒙,首先就是需要在 KonanTarget.kt 新增和 OHOS 平台,同时扩张出 Family.OHOS

  • OHOS_ARM64 : KonanTarget("ohos_arm64", Family.OHOS, Architecture.ARM64)
  • OHOS_X64 : KonanTarget("ohos_x64", Family.OHOS, Architecture.X64)

这两个 Target 也意味着,从 Gradle DSL kotlin { ohosArm64() } 一直到中间 IR 的 lowering 阶段,Kotlin 编译器都知道了鸿蒙平台的存在。

然后就是让 LLVM 后端真能产出能跑的二进制,这一步简单说就两件事:

  • clang 参数:用毕昇 LLVM 19,然后 host-defines 上沿用 Linux 一路,因为鸿蒙底层 libc 是 musl,工具链以 Linux ELF 派生
  • 链接器 :Linker.kt 用 class OhosLinker(targetProperties: OhosConfigurables) : LinkerFlags(...),配套 OhosConfigurables 做 dispatch

那 KMP 到这里 Kotlin 到 ELF 的工具链就这么简单接通了, 然后就是产物:

  • 编译器用鸿蒙官方毕昇 LLVM 19 和 Kotlin/Native 自带 LLVM 解耦

  • 产物大概有:

    • libkn.so(业务通用动态库)
    • libkn.a(静态库,供 hap 二次链接)
    • libkn_api.h(C 头,供宿主 C/C++ 访问 Kotlin 导出 API,和 libkn_api.h 配套)
    • .kexe(可执行)
  • 模块化编译 :通过 emitRuntime / emitStdlib / moduleIncludes 分别产出 runtime、stdlib、业务模块多个 so,可以按需装载、热替换和排查符号问题

  • 缓存:支持 per-file / per-klib 静态缓存,可以加速 Debug 增量构建
  • DFX:内置 hilog 接入、crash 栈解析,Sanitizer 方面支持 ASAN

所以整个流程大概就是: Kotlin 源代码 → Kotlin/Native 编译器(带 OHOS Target) → 毕昇 LLVM 19(OHOS 工具链) → ELF 静态/动态库 (.a/.so/.kexe) ,最终被鸿蒙应用以 dlopen 方式装载:

CMP 鸿蒙

完成 KMP 的基础之后,就是 CMP 在鸿蒙上的 Skia 绘制,目前也有两条路线:

  • 自渲染(skia 路径)
  • 统一渲染(fusionRenderer 路径)

自渲染

自渲染路径和 iOS 的 KN一致,CMP 自己持有一块 GL Surface,自己 swap ,鸿蒙这一侧的载体是提供一个 ArkUI 的 XComponent,暴露一个原生 EGL Surface,外加触摸事件投递:

  • ComposeArkUIViewController 作为入口类,接到 ArkUIViewController 的生命周期回调后,会把 EGL 上下文与 Skia Surface 接起来
  • 帧驱动用 ChoreographerManager 接收鸿蒙 vsync 信号,然后送给 ComposeSceneRender 做组合与重绘

基本都是和 ovCompose 没什么太大区别,一个妈生的。

统一渲染

这个就有意思了,通过 ArkUI RenderNode 作为挂载锚点 ,由 ArkUI 渲染线程驱动反向 draw 回调,Compose 直接在 ArkUI 提供的 Canvas 上完成绘制,fusion 模式下 Compose 不再持有独立 EGL/GPU 上下文 ,所以省去双份 GPU 上下文与离屏 buffer 开销 :

  • JsRenderNode(通过 NAPI / RenderNode JS API 同步)
  • CRenderNode(通过 Native C++ 直接挂载)

不过目前统一渲染 的 ArkUINativeViewFusionRenderNode.kt 文件头是:

但是实现上又是:

所以这个是属于华为的设计,还是和腾讯有关系?我也分不清了,但是看起来还是更多像是华为的实现,或者只是模板污染了?

所以看下来,目前鸿蒙社区版本基本就是继承了 KuiklyBase 和 ovCompose 的实现,算是这两个的分支?而且目前已经合入了 JetBrains 上游 Kotlin 2.2.21 / Compose 1.9.2 ,还在能加了 LTPO/DVSync 自适应帧率、 CommonGC 全新算法替代原 CMS 算法等调整,所以也不全是腾讯的直接迁移。

不过问题来了,未来 KMP 和 CMP 在鸿蒙等于是多分叉?比如:

  • JetBrains 的 KMP/CMP
  • 基于 JetBrains 的腾讯 Kuikly 和 ovCompose
  • 基于 Kuikly 和 ovCompose 的 CPF-KMP-CMP

或者就是后续完全分叉?开发者自己选用哪个?反正我暂时是没搞懂。那么你选的话呀,你会选个?

链接

atomgit.com/CPF-KMP-CMP...

相关推荐
乘风gg1 小时前
OpenClaw 爆火,但”飞书"赢麻了!!!
前端·ai编程·claude
三少爷的鞋2 小时前
Android 协程并发控制:别动线程池,控制好并发语义就够了
android
Oneslide2 小时前
React 纯前端技术栈报告(2026年)
前端
前端一小卒2 小时前
AI 时代,前端工程化要重做一遍
前端
橙子家11 小时前
浏览器缓存之【基础键值存储】:Local storage 和 Session storage
前端
星星在线13 小时前
MusicFree:一个「All in One」的个人音乐服务器,让听歌回归简单
前端·后端
IT_陈寒14 小时前
Redis的SETNX并发问题让我加了三天班
前端·人工智能·后端
demo007x14 小时前
Docling 文档转换以及技术架构分析
前端·后端·程序员
京东云开发者15 小时前
京东市民服务又“上新”!这次是黑龙江“龙易办”
前端