Kotlin Multiplatform for OpenHarmony 实战:kotlinx-serialization JSON 适配

摘要

本文属于 KMP 三方库鸿蒙化适配合集,聚焦 Kotlin 官方序列化库 kotlinx.serialization 在 OpenHarmony 上的适配实践。文章提出「语义层 + 引擎层 + 验收页」的三层架构:语义层用 JsonElement 树与 KSerializer<T> 契约保留原库的纯映射,引擎层复用 ArkTS 自带的 JSON 设施完成最终编解码,验收页在真机上验证嵌套对象的序列化与反序列化。全文只讲本仓库真实落地的代码,并总结了 JSON.parse 类型摩擦、严格模式禁参数属性、手写解析器转义处理等踩坑经验。

目录

一、为什么选它

kotlinx.serialization 是 Kotlin 官方的跨平台序列化库,把"类型化对象 <-> JSON"拆成两层:类型化的 Serializer<T>(描述怎么把 T 编成 JsonElement、怎么解回 T),以及平台无关的 JsonElement 树(JsonPrimitive / JsonObject / JsonArray)。在 KMP 项目里它几乎是"标配"------网络响应、本地缓存、配置落盘都离不了。

到了 OpenHarmony,系统没有 Kotlin 编译器在编译期为 @Serializable 生成 Serializer 的能力,但 ArkTS 运行时自带 ECMAScript 的 JSON 全局对象。所以适配思路是:保留原库"对象 <-> JsonElement 树"的纯映射(语义层),把"JsonElement 树 <-> 字符串"的最终编解码交给系统 JSON 设施(引擎层)。这同样是"真接口真实现",而不是糊一个假壳。

二、适配总思路:三层架构

  1. 语义层(不碰 @kit.*) :定义 JsonElement 树、KSerializer<T> 契约,以及手写 parseJson 解析器(纯算法)。
  2. 引擎层(桥系统 JSON 设施) :OhosSerializationEngine 薄封装系统 JSON,encode/decode 委托给语义层门面。
  3. 验收页 :SerializationDemo 在真机/模拟器上把 User、嵌套 Profile 编码成 JSON 再反解回来。

三、语义层:JsonElement 树 + Serializer 契约

Serialization.ets 只承载数据结构与纯算法,没有任何平台依赖(注意 ArkTS 严格模式禁止构造参数属性,字段显式赋值):

typescript 复制代码
export interface KSerializer<T> {
  readonly descriptor: SerialDescriptor;
  serialize(value: T): JsonElement;
  deserialize(element: JsonElement): T;
}

export class Json {
  encodeToString<T>(value: T, serializer: KSerializer<T>): string {
    return JSON.stringify(serializer.serialize(value).toPlain());
  }
  decodeFromString<T>(text: string, serializer: KSerializer<T>): T {
    return serializer.deserialize(parseJson(text));
  }
}

这与 kotlinx.serialization 的"KSerializer<T> + Json 门面"语义一致------你为每个数据类手写一份 Serializer,剩下的交给门面。

四、为什么手写 JSON 解析器

ArkTS 严格模式下 JSON.parse 返回 Object 类型,之后无法安全做动态属性索引(obj['key'] 会被拦),而 JSON.stringify 对纯数据则完全可用。因此:

  • 编码 :用系统 JSON.stringify(安全、零依赖)。
  • 解码 :放一个手写递归下降 parseJson,把字符串解析成我们自己的 JsonElement 树,再交给 deserialize。

手写解析器其实更贴近原库------kotlinx 的 JSON 解析同样是自实现的,而不是简单调平台 API。

五、引擎层:桥系统 JSON 设施

OhosSerializationEngine.ets 只做一件事:把"平台相关"的编解码交给系统,自己不造轮子。

typescript 复制代码
import { Json, KSerializer } from './Serialization';

export class OhosSerializationEngine {
  private readonly json: Json = new Json();
  encode<T>(value: T, serializer: KSerializer<T>): string {
    return this.json.encodeToString(value, serializer);   // 内部 JSON.stringify
  }
  decode<T>(text: string, serializer: KSerializer<T>): T {
    return this.json.decodeFromString(text, serializer);   // 内部手写 parseJson
  }
}

要点:我们没有引入任何第三方 JSON 库,而是复用鸿蒙/ArkTS 已经稳定提供的 JSON 能力------这正是"真接口真实现"的体现。

六、验收页:真机上验证

我的开发界面如下:

SerializationDemo.ets 定义了 User、Address、Profile(含 User + Address + tags[] 嵌套)以及对应的手写 Serializer。四个按钮:序列化 User、反序列化 User、序列化嵌套 Profile、反序列化 Profile。

运行时能看到:点"序列化 User"输出 {"name":"张三","age":28,"email":"...","active":true};点"反序列化 Profile"能正确还原出 user.name、address.city、tags 数组------证明 JSON 序列化 API 真实生效。

运行效果如下:

七、踩坑小结

  1. JSON.parse 的类型摩擦 :严格模式下返回 Object 不能动态索引,改用自写 parseJson 产出强类型 JsonElement 树。
  2. 严格模式禁参数属性 :constructor(public x) 非法,所有字段用普通参数 + this.x = x。
  3. 手写解析器要处理转义 :\"、\\、\n、\uXXXX 等转义必须覆盖,否则中文/特殊字符会解错。
  4. 嵌套靠组合 :嵌套对象的 Serializer 直接复用子 Serializer(o.put('user', userSerializer.serialize(...))),与原库组合式写法一致。

社区引导

欢迎加入 KMP&CMP 鸿蒙社区:https://atomgit.com/CPF-KMP-CMP

本适配全部源码已开源在 AtomGit:https://atomgit.com/wdracky/kmp-ohos-adapters/tree/main/kotlinx-serialization

如果你在适配过程中用到了 AI 辅助工具,推荐码道(AtomCode)专属通道

https://developer.huaweicloud.com/codeartsco.html?source=dmzntgwatomgit1\&sourcead=dmzntgwatomgiths

相关推荐
银河技术2 小时前
从脚本到 Operator:用 Go 构建可靠的微服务自动扩缩容控制器
开发语言·微服务·golang
GIS数据转换器4 小时前
地下空间综合管廊运营管理平台
大数据·开发语言·人工智能·经验分享·perl
Wang's Blog9 小时前
Java 项目实战: 交友项目:登录链路回顾与今日任务地图
java·开发语言·状态模式·交友
砚底藏山河10 小时前
python量化:行情数据回溯
java·开发语言·python·金融·maven
今年下半年10 小时前
AI智能体项目实战记录(02):初始化 Python 项目
开发语言·人工智能·python·fastapi
Williamtym10 小时前
PickGo Lab实践:用浏览器、Python和MCP串起机器人搬运仿真
开发语言·python·机器人
DongQiShanRen10 小时前
六根硬件映射(四):归属澄清、两处不一致与卷十一总表
开发语言·人工智能·算法·rust·哈希算法·集成学习
CS创新实验室10 小时前
Python 对象“死“了之后去了哪?——引用计数与分代垃圾回收
开发语言·jvm·python
quantdash_cc11 小时前
Pandas 处理分钟级股票行情:从原始数据清洗到 K 线聚合
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash