
Kotlin Multiplatform 三方库 kotlinx-serialization-json 的 OpenHarmony 鸿蒙化适配实战Kotlin/Native 编译 .so NAPI 桥接 ArkTS库版本kotlinx-serialization-json 1.9.1-OHOS-003鸿蒙切片验证环境Kotlin Multiplatform 2.2.21Kotlin 2.2.21-1.0.0 定制版DevEco Studio 26.0.0DevEco 模拟器HarmonyOS 7.0.0API 26在跨平台开发里kotlinx-serialization-json是 Kotlin 生态事实标准的序列化库。但要在鸿蒙上用它绝不是引个包就行——鸿蒙的 Kotlin 支持走Kotlin/Native路线需要把序列化逻辑编译成动态库.so再通过NAPI暴露给 ArkTSUI 层。本文记录我把kotlinx-serialization-json完整跑上鸿蒙的全过程从选对鸿蒙切片版本、Kotlin/Native 编译双 ABI 的.so、NAPI 桥接到修掉一个让 ArkTSJSON.parse崩溃的隐蔽 bug最终在 DevEco 模拟器上 10/10 全绿通过验收。*先睹为快DevEco 模拟器实测10 个序列化用例全部 PASS输出为真实序列化结果* 一、适配目标与整体链路目标很朴素在鸿蒙模拟器里跑一个 ArkTS 应用点一下按钮真实调用Kotlin/Native 里的序列化逻辑把结果返回并渲染出来——以此证明整条链路真正打通而不是 UI 上摆几个写死的字符串。整体链路二、工程结构kmp-serialization-demo/ ├── serialization-core/ # 库模块kotlinx-serialization-json 封装 │ └── src/commonMain/kotlin/ # 公共 API100% 复用上游 ├── example/ │ ├── shared/ # 共享验收逻辑10 个用例 │ │ └── src/commonMain/kotlin/SerializationChecks.kt │ ├── nativeApp/ # Kotlin/Native 桥接层 → libohosserialization.so │ │ └── src/ohosMain/kotlin/NativeBridge.kt # CName 导出 JSON │ └── ohosApp/ # ArkTS 鸿蒙应用 │ └── entry/src/main/ets/pages/Index.ets └── settings.gradle.kts / build.gradle.kts / gradle.propertiesserialization-core封装序列化能力公共 API 完全复用上游example/shared定义 10 个验收用例——基本类型、嵌套对象、集合、默认值填充、sealed 多态、忽略未知键等example/nativeApp把 shared 编译成libohosserialization.soCName导出example/ohosAppArkTS UI通过 NAPI 调用.so。三、适配过程四个关键步骤### 3.1 选对序列化库的鸿蒙切片版本这是第一个、也是最隐蔽的坑。项目最初写的是kotlinx-serialization-json:1.9.0-ohos.1但这个版本在中央仓库和定制仓库里都不存在Gradle 依赖解析直接失败。我列出定制 Nexus 仓库里kotlinx-serialization-json的全部版本发现可用的鸿蒙切片是1.9.1-OHOS-003并通过 HTTP HEAD 请求确认它确实带ohosArm64/ohosX64的 klibkotlinx-serialization-json-ohosArm64-1.9.1-OHOS-003.klib ✅ kotlinx-serialization-json-ohosx64-1.9.1-OHOS-003.klib ✅把版本改为1.9.1-OHOS-003后依赖解析通过。经验鸿蒙生态的 KMP 库版本号往往是x.y.z-OHOS-NNN这种定制切片不能想当然写 upstream 版本号。先查仓库里真实存在什么再写进build.gradle.kts。3.2 用 Kotlin/Native 编译出双 ABI 的 .so鸿蒙的 Kotlin/Native target 是ohosArm64真机和ohosX64模拟器。用 JDK 21 作为JAVA_HOME执行$env:JAVA_HOME C:/Users/nwu/Desktop/z_pig/jdk-21.0.2.\gradlew.bat :example:nativeApp:linkReleaseSharedOhosArm64 :example:nativeApp:linkReleaseSharedOhosX64产物example/nativeApp/build/bin/ohosArm64/releaseShared/libohosserialization.so example/nativeApp/build/bin/ohosX64/releaseShared/libohosserialization.so把两个 ABI 的.so分别拷到 ArkTS 工程的entry/libs/arm64-v8a/和entry/libs/x86_64/。3.3 NAPI 桥接从 ArkTS 调进 Kotlin/NativeKotlin 侧用CName把结果以 JSON 字符串导出CName(runChecks)funrunChecks():StringbuildJsonResult(runAllChecks())ArkTS 侧引入 NAPI 薄层并调用importserializationNativefromlibserialization.so;constjsonStr:stringserializationNative.runChecks();constparsedJSON.parse(jsonStr)asCheckResult;this.resultparsed;UI 触发入口如下——深色现代化界面渐变背景 氛围光斑、顶部胶囊标签KMP 2.2.21 / HarmonyOS 7.0.0 / API 26、发光运行按钮、空状态{ }占位。*初始页深蓝渐变 胶囊标签 发光按钮点击「运行全部验收用例」触发 NAPI 调用*3.4 修复一个让 JSON.parse 崩溃的 bug链路打通后UI 却报Unexpected end Text in JSON。排查发现根因不在 NAPI而在 Kotlin 侧buildJsonResult()——它手工拼 JSON 字符串时只转义了引号没转义换行符。而用例里Json { prettyPrint true }会让output字段带大量真实换行导致整个返回串不是合法 JSONArkTS 一解析就崩。修复方式是加一个完整的转义函数privatefunjsonEscape(s:String):StringbuildString(s.length){for(cins){when(c){-append(\\\)\\-append(\\\\)\n-append(\\n)\r-append(\\r)\t-append(\\t)else-append(c)}}}经验跨语言传 JSON永远不要手工拼字符串。如果必须拼转义要完整引号、反斜杠、换行、回车、制表符。更稳妥的做法是直接用 kotlinx-serialization 自己序列化结果对象。四、运行效果DevEco 模拟器实测明细列表每条用例一张磨砂玻璃卡状态圆点 PASS 徽标 等宽字体代码块展示真实序列化输出。下面三段分别对应不同类型用例的实测结果。基本类型与嵌套对象——输出是真实 JSON如{id: 1, name: 张三}*基本数据类序列化、嵌套对象全部 PASS*sealed 多态——成功绿点与失败红点用例的红绿对比清晰可见*sealed class 多态序列化/反序列化类型判别字段正确还原*Map 与默认值填充——含extensionProperties等复杂结构*Map 序列化、忽略未知键、默认值填充等全部 PASS*应用已正常安装到 DevEco 模拟器并可拉起*DevEco 模拟器桌面应用入口图标正常显示*10 个用例全部 PASS覆盖基本类型序列化、嵌套对象、集合、Map、默认值填充、sealed 多态、忽略未知键等输出均为真实序列化结果而非 mock。五、FAQQ1Gradle 依赖解析失败提示找不到1.9.0-ohos.1这个版本不存在。查鸿蒙定制仓库maven.eazytec-cloud.com里真实存在的 OHOS 切片版本本文用1.9.1-OHOS-003。Q2Kotlin/Native 编译报 JDK 相关错误用 JDK 21 作为JAVA_HOMEDevEco 自带 JBR 或 Temurin 均可。Q3命令行 hvigor 构建报Invalid value of DEVECO_SDK_HOME先export DEVECO_SDK_HOMEDevEco 安装目录/sdk再hvigorw --stop-daemon后重试。Q4往hvigor-config.json5的dependencies里写了说明文字pnpm install 失败该字段只放真实 npm 包别写libohosserialization.so (arm64-v8a)这类描述否则 pnpm 会当依赖解析报错。Q5ArkTSJSON.parse报Unexpected end Text in JSON多半是 Kotlin 侧手工拼 JSON 没转义换行/引号。补全jsonEscape或直接用序列化库生成结果字符串。Q6hdc 自动化点击按钮没反应别凭截图比例估算坐标用hdc shell uitest dumpLayout查控件真实bounds再按中心点uitest uiInput click x y。六、总结与参考把kotlinx-serialization-json跑上鸿蒙本质是打通KMP → Kotlin/Native(ohos target) → .so → NAPI → ArkTS这条链。关键不在某一步多难而在于每一步都有看起来对但其实不对的细节版本切片、JDK、DEVECO_SDK_HOME、JSON 转义、点击坐标。这次 10/10 全绿证明整条链路真实可用。OpenHarmony 三方库社区地址https://atomgit.com/oh-tpcgithub 三方库地址https://github.com/Kotlin/kotlinx.serialization官方文档地址https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/serialization-guide.md鸿蒙定制仓库地址https://maven.eazytec-cloud.com/nexus/repository/maven-public/鸿蒙适配版https://atomgit.com/oh-tpc/serialization-core