Loading...
Loading...
Kuikly 自定义 Module 开发助手。指导如何创建自定义 Module,扩展原声API。覆盖完整开发流程:Kuikly 侧 Module 定义、Pager/ComposeContainer 注册、各平台 Native 侧实现、Module 注册,及使用。当用户需要自定义 Module、扩展原生 API、实现 Kuikly 与 Native 双向通信、在各平台实现 Module 的 Native 侧逻辑时使用。
npx skill4agent add tencent-tds/kuiklyui-ai kuikly-expand-apimoduleNamesyncToNativeMethodasyncToNativeMethodmoduleName()ModulemoduleName()toNativesyncToNativeMethodasyncToNativeMethodcreateExternalModules()acquireModuleimport com.tencent.kuikly.core.module.Module
import com.tencent.kuikly.core.module.CallbackFn
import com.tencent.kuikly.core.nvi.serialization.json.JSONObject
class MyLogModule : Module() {
override fun moduleName(): String = "KRMyLogModule"
companion object {
const val MODULE_NAME = "KRMyLogModule"
}
}| 方法 | 调用方式 | Native 执行线程 | 参数类型 | 回调类型 |
|---|---|---|---|---|
| 同步 | Kuikly 线程 | JSONObject(序列化为 JSON 字符串) | |
| 同步 | Kuikly 线程 | 基本类型数组(String/Int/Float/ByteArray) | |
| 异步 | 主线程 | JSONObject(序列化为 JSON 字符串) | |
| 异步 | 主线程 | 基本类型数组(String/Int/Float/ByteArray) | |
| 通用底层方法 | 取决于 syncCall | Any? | |
fun log(content: String) {
asyncToNativeMethod(
"log",
JSONObject().apply { put("content", content) },
null
)
}fun logWithCallback(content: String, callbackFn: CallbackFn) {
asyncToNativeMethod(
"logWithCallback",
JSONObject().apply { put("content", content) },
callbackFn
)
}fun syncLog(content: String): String {
return syncToNativeMethod(
"syncLog",
JSONObject().apply { put("content", content) },
null
)
}fun uploadData(bytes: ByteArray): Any? {
return syncToNativeMethod(
"uploadData",
arrayOf<Any>(bytes),
null
)
}fun registerListener(callbackFn: CallbackFn): CallbackRef {
val result = toNative(
true, // keepCallbackAlive: callback 不会被自动销毁
"registerListener",
null,
callbackFn,
false
)
return result.callbackRef!!
}
// 手动移除回调
fun unregisterListener(callbackRef: CallbackRef) {
removeCallback(callbackRef)
}createExternalModules()import com.tencent.kuikly.core.annotations.Page
import com.tencent.kuikly.core.module.Module
@Page("MyPage")
internal class MyPage : Pager() {
override fun createExternalModules(): Map<String, Module>? {
return mapOf(
MyLogModule.MODULE_NAME to MyLogModule()
)
}
// 如果有基类 BasePager 已注册了其他 Module,需要合并:
// override fun createExternalModules(): Map<String, Module>? {
// val modules = (super.createExternalModules() as? HashMap) ?: hashMapOf()
// modules[MyLogModule.MODULE_NAME] = MyLogModule()
// return modules
// }
override fun body(): ViewBuilder { ... }
}import com.tencent.kuikly.compose.ComposeContainer
import com.tencent.kuikly.compose.setContent
import com.tencent.kuikly.core.annotations.Page
import com.tencent.kuikly.core.module.Module
@Page("MyComposePage")
class MyComposePage : ComposeContainer() {
// 注册方式与 Kuikly DSL 完全一致
override fun createExternalModules(): Map<String, Module>? {
return mapOf(
MyLogModule.MODULE_NAME to MyLogModule()
)
}
override fun willInit() {
super.willInit()
setContent {
MyScreen()
}
}
}override fun created() {
super.created()
val myLogModule = acquireModule<MyLogModule>(MyLogModule.MODULE_NAME)
// 异步调用
myLogModule.log("test log")
// 异步调用带回调
myLogModule.logWithCallback("log with callback") { data ->
val result = data // Native 侧返回的 JSONObject
}
// 同步调用
val result = myLogModule.syncLog("sync log")
}import androidx.compose.runtime.Composable
import com.tencent.kuikly.compose.ui.platform.LocalActivity
import com.tencent.kuikly.core.pager.Pager
@Composable
fun MyScreen() {
val pager = LocalActivity.current.getPager() as Pager
val myLogModule = pager.acquireModule<MyLogModule>(MyLogModule.MODULE_NAME)
// 异步调用
myLogModule.log("test log")
// 异步调用带回调
myLogModule.logWithCallback("log with callback") { data ->
val result = data // Native 侧返回的 JSONObject
}
// 同步调用
val result = myLogModule.syncLog("sync log")
}callmethod💡 鸿蒙平台备注: 鸿蒙提供 ArkTS 和 C 两种实现方式,一般情况只需选择 ArkTS 实现即可。
| 平台 | 基类 | 注册方式 | 注意事项 |
|---|---|---|---|
| Android | | | 重写 |
| iOS | | 类名必须与 Kuikly 侧 moduleName 一致(运行时动态创建) | 方法名与 Kuikly 侧 methodName 一致,参数固定为 |
| 鸿蒙 (ArkTS) | | | 需实现 |
| 鸿蒙 (C) | | | 返回值 KRAnyData 由框架释放 |
| H5 | | | 同 Android |
| 小程序 | | | 可通过 |
| 平台 | 支持的数据类型 |
|---|---|
| Android | |
| iOS | |
| 鸿蒙 | |
| H5/小程序 | |
| 类目 | 序列化方式 | 涉及类型 |
|---|---|---|
| 基础类型 | 直接透传 | |
| 二进制数据 | 直接透传 | |
| JSON 数据 | JSON 字符串 | |
| 集合类型 | JSON 字符串 | |
| 特殊规则 | 直接透传 | Array 中包含 |
⚠️和syncToNativeMethod传入 JSONObject 参数时会序列化为 JSON 字符串,不支持 ByteArray 二进制数据。传输二进制请使用asyncToNativeMethod参数的重载方法。Array<Any>
| ❌ 错误做法 | ✅ 正确做法 |
|---|---|
| Module 名字 Kuikly 侧与 Native 侧不一致 | 确保 |
在 | 在 |
| 同步调用中执行耗时操作 | 同步调用在 Kuikly 线程执行,避免耗时操作阻塞渲染 |
忘记在 | 自定义 Module 必须在 Pager 的 |
| 用 JSONObject 参数传输二进制数据 | 使用 |
| iOS 侧 Module 类名与 Kuikly 侧不一致 | iOS 通过类名动态创建 Module,类名必须与 |
iOS 侧用 Swift 实现但未加 | Swift 实现的 Module 需要 |
| 常驻回调忘记手动移除 | |
Compose DSL 中直接调用 | 在 |
Compose DSL 中忘记 import | 需 |