Kuikly 扩展原生 API 的完整流程

Kuikly 扩展原生 API 的完整流程,​保持原始代码完整性,并通过多端对比(Kuikly/Android/iOS/鸿蒙)和参数传递、回调通信的详细说明:


1. Kuikly 侧 Module 定义与调用

​(1)定义 Module 类

kotlin 复制代码
class MyLogModule : Module() {
    override fun moduleName(): String = "KRMyLogModule" // 必须与原生侧一致

    // 无返回值调用
    fun log(content: String) {
        toNative(
            keepCallbackAlive = false,
            methodName = "log",          // 原生侧方法名
            param = content,             // 传递字符串参数
            callback = null,             // 无回调
            syncCall = false             // 异步调用
        )
    }

    // 异步回调
    fun logWithCallback(content: String, callbackFn: CallbackFn) {
        toNative(
            keepCallbackAlive = false,
            methodName = "logWithCallback",
            param = content,
            callback = callbackFn,       // 原生侧通过此回调返回结果
            syncCall = false
        )
    }

    // 同步调用(阻塞当前线程)
    fun syncLog(content: String): String {
        return toNative(
            keepCallbackAlive = false,
            methodName = "syncLog",
            param = content,
            callback = null,
            syncCall = true              // 同步调用,直接返回结果
        ).toString()
    }
}

​(2)注册 Module

kotlin 复制代码
internal class TestPage : Pager() {
    override fun createExternalModules(): Map<String, Module>? {
        return mapOf("KRMyLogModule" to MyLogModule()) // Key 必须与 moduleName() 一致
    }

    override fun created() {
        val logModule = acquireModule<MyLogModule>("KRMyLogModule")
        logModule.log("Hello") // 异步无回调
        logModule.logWithCallback("World") { result ->
            // 原生侧回调的 JSON 结果
            println("Callback result: $result")
        }
        val syncResult = logModule.syncLog("Sync") // 同步阻塞
    }
}

2. 原生侧实现对比

Android 侧

kotlin 复制代码
class KRMyLogModule : KuiklyRenderBaseModule() {
    // 统一入口,根据 methodName 分发调用
    override fun call(method: String, params: String?, callback: KuiklyRenderCallback?): Any? {
        return when (method) {
            "log" -> log(params ?: "")
            "logWithCallback" -> logWithCallback(params ?: "", callback)
            "syncLog" -> syncLog(params ?: "")
            else -> super.call(method, params, callback)
        }
    }

    private fun log(content: String) {
        Log.d("Kuikly", content) // 简单打印
    }

    private fun logWithCallback(content: String, callback: KuiklyRenderCallback?) {
        Log.d("Kuikly", content)
        callback?.invoke(mapOf("result" to "OK")) // 回调结果给 Kuikly
    }

    private fun syncLog(content: String): String {
        Log.d("Kuikly", content)
        return "Success" // 同步返回字符串
    }
}

// 注册 Module(在 KuiklyRenderViewDelegatorDelegate 实现类中)
override fun registerExternalModule(export: IKuiklyRenderExport) {
    export.moduleExport("KRMyLogModule") { KRMyLogModule() } // Key 必须一致
}

iOS 侧

less 复制代码
// KRMyLogModule.h
@interface KRMyLogModule : KRBaseModule
@end

// KRMyLogModule.m
@implementation KRMyLogModule

// 方法名必须与 Kuikly 侧 methodName 一致
- (void)log:(NSDictionary *)args {
    NSString *content = args[HR_PARAM_KEY]; // 参数键固定
    NSLog(@"Kuikly Log: %@", content);
}

- (void)logWithCallback:(NSDictionary *)args {
    NSString *content = args[HR_PARAM_KEY];
    NSLog(@"Kuikly Log: %@", content);
    KuiklyRenderCallback callback = args[KR_CALLBACK_KEY]; // 回调键固定
    callback(@{@"result": @"OK"}); // 回调结果
}

- (id)syncLog:(NSDictionary *)args {
    NSString *content = args[HR_PARAM_KEY];
    NSLog(@"Kuikly Log: %@", content);
    return @"Success"; // 同步返回
}

@end

鸿蒙侧(ArkTS)​

typescript 复制代码
export class KRMyLogModule extends KuiklyRenderBaseModule {
    static readonly MODULE_NAME = "KRMyLogModule";

    syncMode(): boolean { return true; } // 允许同步调用

    call(method: string, params: KRAny, callback: KuiklyRenderCallback | null): KRAny {
        switch (method) {
            case 'log':
                console.log(`Kuikly Log: ${params as string}`);
                break;
            case 'logWithCallback':
                console.log(`Kuikly Log: ${params as string}`);
                callback?.({ result: "OK" }); // 回调结果
                break;
            case 'syncLog':
                console.log(`Kuikly Log: ${params as string}`);
                return "Success"; // 同步返回
        }
        return null;
    }
}

// 注册 Module(在 IKuiklyViewDelegate 实现类中)
getCustomRenderModuleCreatorRegisterMap(): Map<string, KRRenderModuleExportCreator> {
    const map = new Map<string, KRRenderModuleExportCreator>();
    map.set(KRMyLogModule.MODULE_NAME, () => new KRMyLogModule());
    return map;
}

3. 参数传递与回调通信

参数类型支持

Kuikly 侧 原生侧接收方式
String Android/iOS/鸿蒙均通过 params字段获取
Int/Double 自动转换为原生数字类型
Array 转换为原生数组(如 NSArray/List
JSON 对象 需序列化为字符串传递,原生侧解析

回调通信

  • 异步回调​:

    Kuikly 侧通过 CallbackFn接收原生侧的 callback.invoke(result)callback(result)

  • 同步返回​:

    原生侧直接返回 String或基本类型(如 Android 的 Any?、iOS 的 id)。

线程模型

调用方式 Kuikly 线程 原生侧线程
异步调用 非 UI 线程 Android/iOS 主线程
同步调用 阻塞当前线程 原生侧子线程(Android)

4. 关键注意事项

  1. 命名一致性

    • Kuikly 的 moduleName()、注册时的 Key、原生类名必须完全一致。
    • 方法名(如 log)需在 Kuikly 和原生侧严格匹配。
  2. 参数键固定

    • iOS 使用 HR_PARAM_KEYKR_CALLBACK_KEY获取参数和回调对象。
  3. JSON 处理

    • 复杂数据需在 Kuikly 侧序列化为 String,原生侧反序列化(如 JSON.parse)。
  4. 同步调用限制

    • 鸿蒙需显式启用 syncMode(): boolean = true

通过以上对比和完整代码展示,可以清晰看到 Kuikly 扩展原生 API 的多端协作机制,包括模块定义、注册、参数传递和回调通信的全流程。

相关推荐
Apifox2 小时前
Apifox 11 月更新|AI 生成测试用例能力持续升级、JSON Body 自动补全、支持为响应组件添加描述和 Header
前端·后端·测试
木易士心2 小时前
深入剖析:按下 F5 后,浏览器前端究竟发生了什么?
前端·javascript
在掘金801102 小时前
vue3中使用medium-zoom
前端·vue.js
xump2 小时前
如何在DevTools选中调试一个实时交互才能显示的元素样式
前端·javascript·css
折翅嘀皇虫2 小时前
fastdds.type_propagation 详解
java·服务器·前端
Front_Yue2 小时前
深入探究跨域请求及其解决方案
前端·javascript
wordbaby2 小时前
React Native 进阶实战:基于 Server-Driven UI 的动态表单架构设计
前端·react native·react.js
抱琴_2 小时前
【Vue3】我用 Vue 封装了个 ECharts Hooks,同事看了直接拿去复用
前端·vue.js
风止何安啊2 小时前
JS 里的 “变量租房记”:闭包是咋把变量 “扣” 下来的?
前端·javascript·node.js
Danny_FD2 小时前
用 ECharts markLine 标注节假日
前端·echarts