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

相关推荐
陈随易9 小时前
有生之年系列,Nodejs进程管理pm2 v7.0发布
前端·后端·程序员
冰暮流星9 小时前
javascript之事件代理/事件委托
前端
陈随易10 小时前
AI时代,你还在坚持手搓文章吗
前端·后端·程序员
里欧跑得慢12 小时前
17. Flutter Hero动画实现:让界面过渡更加优雅
前端·css·flutter·web
IT_陈寒13 小时前
Vue的这个响应式陷阱,我debug了一整天才爬出来
前端·人工智能·后端
kyriewen13 小时前
前端测试:别为了100%覆盖率而写测试,那是自欺欺人
前端·javascript·单元测试
去伪存真13 小时前
我自己写的第一个skills--project-core-standards
前端·agent
Data_Journal13 小时前
如何使用cURL更改User Agent
大数据·服务器·前端·javascript·数据库
竹林81814 小时前
wagmi v2 多链钱包切换:一个 Uniswap 仿盘项目让我踩了三天坑
前端·javascript
donecoding14 小时前
Playwright MCP 页面捕获:Snapshot、截图、HTML 到底选哪个?
前端·ai编程·前端工程化