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

相关推荐
whysqwhw3 小时前
Hippy 跨平台框架扩展原生自定义组件
前端
OEC小胖胖3 小时前
页面间的导航:`<Link>` 组件和 `useRouter`
前端·前端框架·web·next.js
faimi4 小时前
🚀程序员必收藏!最全Git命令手册:解决90%团队协作难题
前端·gitlab
coooliang4 小时前
【鸿蒙 NEXT】V1迁移V2状态管理
java·前端·harmonyos
程序员码歌4 小时前
零代码AI编程实战-热搜从0到1技术方案
前端·ai编程·cursor
kk不中嘞5 小时前
浅谈前端框架
前端·vue.js·react.js·前端框架
服务端技术栈5 小时前
历时 1 个多月,我的第一个微信小程序「图片转 Excel」终于上线了!
前端·后端·微信小程序
一个很老的小萌新5 小时前
json 解析 [{“id“:1,“name“:“apple“},{“id“:2,“name“:“banana“}]
java·前端·json
yanlele5 小时前
前端面试第 78 期 - 2025.09.07 更新 Nginx 专题面试总结(12 道题)
前端·javascript·面试