后端与接口
在 Kuikly 中扩展原生 API 时如何开发自定义…
当需要让 Kuikly 调用平台原生能力、实现 Kuikly 与 Native 双向通信时,按此流程在 Kuikly 侧定义 Module 并在各目标平台实现 Native 侧逻辑。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 38/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 59/100 ×0.15
适用场景
在 Kuikly 中扩展原生 API 时特定
解决思路
- 新建 Module 类继承 `Module`,实现 `moduleName()` 方法,并确保 Kuikly 侧 `moduleName()` 返回值与 Native 侧注册名完全一致。
- 在 Module 中编写业务 API 方法,通过 `toNative` / `syncToNativeMethod` / `asyncToNativeMethod` 与 Native 通信;同步调用在 Kuikly 线程执行,异步调用在主线程执行,同步调用避免耗时操作。
- 异步无返回值调用使用 `asyncToNativeMethod("log", JSONObject().apply { put("content", content) }, null)`。
- 异步带回调调用使用 `asyncToNativeMethod("logWithCallback", JSONObject().apply { put("content", content) }, callbackFn)`。
- 同步有返回值调用使用 `syncToNativeMethod("syncLog", JSONObject().apply { put("content", content) }, null)` 并返回其结果。
- 传输二进制数据时使用 `Array<Any>` 参数重载:`syncToNativeMethod("uploadData", arrayOf<Any>(bytes), null)`,因为 JSONObject 参数会被序列化为 JSON 字符串、不支持 ByteArray。
- 常驻回调使用 `toNative(true, "registerListener", null, callbackFn, false)` 并保存返回的 `result.callbackRef`,在页面销毁前调用 `removeCallback(callbackRef)` 手动移除。
- 在 Pager 或 ComposeContainer 的 `createExternalModules()` 中注册 Module,返回 `mapOf(MyLogModule.MODULE_NAME to MyLogModule())`;若基类已注册其他 Module,需先取 `super.createExternalModules()` 合并后再加入。
- 在 Kuikly DSL 中于 `created()` 或之后通过 `acquireModule<MyLogModule>(MyLogModule.MODULE_NAME)` 获取并使用 Module。
- 在 Compose DSL 中于 `@Composable` 函数内通过 `LocalActivity.current.getPager() as Pager` 再调用 `acquireModule` 获取 Module,并 import `com.tencent.kuikly.compose.ui.platform.LocalActivity`。
- Native 侧只需在业务需要支持的平台上实现,无需实现所有平台;先确定目标平台(Android/iOS/鸿蒙/H5/小程序)。
- 在目标平台宿主工程中创建对应 Module 类:Android/H5/小程序继承 `KuiklyRenderBaseModule()` 并在 `registerExternalModule` 中用 `moduleExport(name) { Module() }` 注册;iOS 继承 `KRBaseModule` 且类名必须与 Kuikly 侧 moduleName 一致(运行时动态创建),方法名与 methodName 一致、参数固定为 `NSDictionary`,Swift 实现需加 `@objc` 或 `@objcMembers`;鸿蒙 ArkTS 继承 `KuiklyRenderBaseModule` 并在 `getCustomRenderModuleCreatorRegisterMap` 中注册且实现 `syncMode()` 指定同步/异步模式;鸿蒙 C 使用 `KRRenderModuleRegisterV2` 并在 `InitKuikly` 中注册,返回值 KRAnyData 由框架释放。
- 实现 `call` 方法,根据 `method` 分发处理(Android 重写 `call(method, params: Any?, callback)` 或 `call(method, params: String?, callback)`)。
- 将 Module 注册到 Kuikly 框架,并注意各平台支持的数据类型:Android 支持 String/Int/Long/Float/Double/Boolean/ByteArray/Map/List/JSONObject;iOS 支持 NSString/NSNumber/BOOL/NSData/NSDictionary/NSArray;鸿蒙支持 String/Int/Long/Float/Double/Bool/ByteArray/Array/Map/Record;H5/小程序支持 String/Int/Long/Float/Double/Boolean/Array/Map/List/JSONObject/JSONArray。
- 遵循数据序列化规则:基础类型(String/Int/Float/Double/Boolean/NSNumber)直接透传;二进制数据(ByteArray/NSData/ArrayBuffer)直接透传;JSON 数据(JSONObject/JSONArray)序列化为 JSON 字符串;集合类型(Map/Record/List/NSDictionary/NSArray/Array)序列化为 JSON 字符串;Array 中包含 ByteArray/NSData 时直接透传。
适用边界 · 注意事项
- 不需要扩展平台原生能力、仅使用 Kuikly 内置能力时无需自定义 Module。
- 只需支持部分平台时不必为所有平台实现 Native 侧 Module。
- 不要在 `created` 之前获取 Module(Kuikly DSL),也不要在 Compose DSL 的 `setContent` 之前获取。
- 不要在同步调用中执行耗时操作,以免阻塞 Kuikly 线程渲染。