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 的多端协作机制,包括模块定义、注册、参数传递和回调通信的全流程。

相关推荐
JIngJaneIL22 分钟前
基于java+ vue农产投入线上管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot
天外天-亮1 小时前
v-if、v-show、display: none、visibility: hidden区别
前端·javascript·html
jump_jump1 小时前
手写一个 Askama 模板压缩工具
前端·性能优化·rust
be or not to be1 小时前
HTML入门系列:从图片到表单,再到音视频的完整实践
前端·html·音视频
90后的晨仔2 小时前
在macOS上无缝整合:为Claude Code配置魔搭社区免费API完全指南
前端
沿着路走到底2 小时前
JS事件循环
java·前端·javascript
子春一22 小时前
Flutter 2025 可访问性(Accessibility)工程体系:从合规达标到包容设计,打造人人可用的数字产品
前端·javascript·flutter
白兰地空瓶3 小时前
别再只会调 API 了!LangChain.js 才是前端 AI 工程化的真正起点
前端·langchain
jlspcsdn4 小时前
20251222项目练习
前端·javascript·html
行走的陀螺仪4 小时前
Sass 详细指南
前端·css·rust·sass