diff --git a/zh-cn/application-dev/reference/apis-arkui/Readme-CN.md b/zh-cn/application-dev/reference/apis-arkui/Readme-CN.md index ccb096e9bdd11cf4a1c3dfe31309b64fbf0c530a..83a2c7d522741357f5569f3321b5b0b3d9994d6a 100644 --- a/zh-cn/application-dev/reference/apis-arkui/Readme-CN.md +++ b/zh-cn/application-dev/reference/apis-arkui/Readme-CN.md @@ -543,6 +543,8 @@ - [NativeDisplayManager_DisplayColorSpace](capi-nativedisplaymanager-displaycolorspace.md) - [NativeDisplayManager_DisplayInfo](capi-nativedisplaymanager-displayinfo.md) - [NativeDisplayManager_DisplaysInfo](capi-nativedisplaymanager-displaysinfo.md) + - 多线程 + - [多线程NDK接口说明](../../ui/ndk-build-on-multi-thread-api.md) - 错误码 - UI界面 - [动画错误码](errorcode-animator.md) diff --git a/zh-cn/application-dev/reference/apis-arkui/_ark_u_i___native_module.md b/zh-cn/application-dev/reference/apis-arkui/_ark_u_i___native_module.md index ffdc6460a07b6b2ccfbe192dec582cccb6e76efc..19808b52e386eef4df92d580e0ca3b066fe6df53 100644 --- a/zh-cn/application-dev/reference/apis-arkui/_ark_u_i___native_module.md +++ b/zh-cn/application-dev/reference/apis-arkui/_ark_u_i___native_module.md @@ -279,7 +279,7 @@ | [ArkUI_ListItemSwipeEdgeEffect](#arkui_listitemswipeedgeeffect) { ARKUI_LIST_ITEM_SWIPE_EDGE_EFFECT_SPRING = 0, ARKUI_LIST_ITEM_SWIPE_EDGE_EFFECT_NONE } | 定义 Listitem 组件SwipeAction方法的滚动模式。 | | [ArkUI_AnimationStatus](#arkui_animationstatus) { ARKUI_ANIMATION_STATUS_INITIAL, ARKUI_ANIMATION_STATUS_RUNNING, ARKUI_ANIMATION_STATUS_PAUSED, ARKUI_ANIMATION_STATUS_STOPPED } | 定义帧动画的播放状态。 | | [ArkUI_AnimationFillMode](#arkui_animationfillmode) { ARKUI_ANIMATION_FILL_MODE_NONE, ARKUI_ANIMATION_FILL_MODE_FORWARDS, ARKUI_ANIMATION_FILL_MODE_BACKWARDS, ARKUI_ANIMATION_FILL_MODE_BOTH } | 定义帧动画组件在动画开始前和结束后的状态。 | -| [ArkUI_ErrorCode](#arkui_errorcode) {
ARKUI_ERROR_CODE_NO_ERROR = 0, ARKUI_ERROR_CODE_PARAM_INVALID = 401, ARKUI_ERROR_CODE_CAPI_INIT_ERROR = 500, ARKUI_ERROR_CODE_INTERNAL_ERROR = 100001,
ARKUI_ERROR_CODE_XCOMPONENT_STATE_INVALID = 103501, ARKUI_ERROR_CODE_ATTRIBUTE_OR_EVENT_NOT_SUPPORTED = 106102, ARKUI_ERROR_CODE_ARKTS_NODE_NOT_SUPPORTED = 106103, ARKUI_ERROR_CODE_ADAPTER_NOT_BOUND = 106104,
ARKUI_ERROR_CODE_ADAPTER_EXIST = 106105, ARKUI_ERROR_CODE_CHILD_NODE_EXIST = 106106, ARKUI_ERROR_CODE_NODE_EVENT_PARAM_INDEX_OUT_OF_RANGE = 106107, ARKUI_ERROR_CODE_NODE_EVENT_PARAM_INVALID = 106108,
ARKUI_ERROR_CODE_NODE_EVENT_NO_RETURN = 106109, ARKUI_ERROR_CODE_NODE_INDEX_INVALID = 106200, ARKUI_ERROR_CODE_GET_INFO_FAILED = 106201, ARKUI_ERROR_CODE_BUFFER_SIZE_ERROR = 106202,
ARKUI_ERROR_CODE_NODE_NOT_ON_MAIN_TREE = 106203, ARKUI_ERROR_CODE_FOCUS_NON_FOCUSABLE = 150001, ARKUI_ERROR_CODE_FOCUS_NON_FOCUSABLE_ANCESTOR = 150002, ARKUI_ERROR_CODE_FOCUS_NON_EXISTENT = 150003,
ARKUI_ERROR_CODE_COMPONENT_SNAPSHOT_TIMEOUT = 160002, ARKUI_ERROR_CODE_NON_SCROLLABLE_CONTAINER = 180001, ARKUI_ERROR_CODE_BUFFER_SIZE_NOT_ENOUGH = 180002, ARKUI_ERROR_CODE_NOT_CLONED_POINTER_EVENT = 180003,
ARKUI_ERROR_CODE_POST_CLONED_COMPONENT_STATUS_ABNORMAL = 180004, ARKUI_ERROR_CODE_POST_CLONED_NO_COMPONENT_HIT_TO_RESPOND_TO_THE_EVENT = 180005, ARKUI_ERROR_INPUT_EVENT_TYPE_NOT_SUPPORTED = 180006,
ARKUI_ERROR_CODE_INVALID_STYLED_STRING = 180101, ARKUI_ERROR_CODE_UI_CONTEXT_INVALID = 190001,
ARKUI_ERROR_CODE_CALLBACK_INVALID = 190002, ARKUI_ERROR_CODE_RECOGNIZER_TYPE_NOT_SUPPORTED = 180102, ARKUI_ERROR_CODE_DRAG_DROP_OPERATION_NOT_ALLOWED = 190004
} | 定义错误码枚举值。 | +| [ArkUI_ErrorCode](#arkui_errorcode) {
ARKUI_ERROR_CODE_NO_ERROR = 0, ARKUI_ERROR_CODE_PARAM_INVALID = 401, ARKUI_ERROR_CODE_CAPI_INIT_ERROR = 500, ARKUI_ERROR_CODE_INTERNAL_ERROR = 100001,
ARKUI_ERROR_CODE_XCOMPONENT_STATE_INVALID = 103501, ARKUI_ERROR_CODE_ATTRIBUTE_OR_EVENT_NOT_SUPPORTED = 106102, ARKUI_ERROR_CODE_ARKTS_NODE_NOT_SUPPORTED = 106103, ARKUI_ERROR_CODE_ADAPTER_NOT_BOUND = 106104,
ARKUI_ERROR_CODE_ADAPTER_EXIST = 106105, ARKUI_ERROR_CODE_CHILD_NODE_EXIST = 106106, ARKUI_ERROR_CODE_NODE_EVENT_PARAM_INDEX_OUT_OF_RANGE = 106107, ARKUI_ERROR_CODE_NODE_EVENT_PARAM_INVALID = 106108,
ARKUI_ERROR_CODE_NODE_EVENT_NO_RETURN = 106109, ARKUI_ERROR_CODE_NODE_INDEX_INVALID = 106200, ARKUI_ERROR_CODE_GET_INFO_FAILED = 106201, ARKUI_ERROR_CODE_BUFFER_SIZE_ERROR = 106202,
ARKUI_ERROR_CODE_NODE_NOT_ON_MAIN_TREE = 106203, ARKUI_ERROR_CODE_ON_INVALID_THREAD = 106204, ARKUI_ERROR_CODE_FOCUS_NON_FOCUSABLE = 150001, ARKUI_ERROR_CODE_FOCUS_NON_FOCUSABLE_ANCESTOR = 150002, ARKUI_ERROR_CODE_FOCUS_NON_EXISTENT = 150003,
ARKUI_ERROR_CODE_COMPONENT_SNAPSHOT_TIMEOUT = 160002, ARKUI_ERROR_CODE_NON_SCROLLABLE_CONTAINER = 180001, ARKUI_ERROR_CODE_BUFFER_SIZE_NOT_ENOUGH = 180002, ARKUI_ERROR_CODE_NOT_CLONED_POINTER_EVENT = 180003,
ARKUI_ERROR_CODE_POST_CLONED_COMPONENT_STATUS_ABNORMAL = 180004, ARKUI_ERROR_CODE_POST_CLONED_NO_COMPONENT_HIT_TO_RESPOND_TO_THE_EVENT = 180005, ARKUI_ERROR_INPUT_EVENT_TYPE_NOT_SUPPORTED = 180006,
ARKUI_ERROR_CODE_INVALID_STYLED_STRING = 180101, ARKUI_ERROR_CODE_UI_CONTEXT_INVALID = 190001,
ARKUI_ERROR_CODE_CALLBACK_INVALID = 190002, ARKUI_ERROR_CODE_RECOGNIZER_TYPE_NOT_SUPPORTED = 180102, ARKUI_ERROR_CODE_DRAG_DROP_OPERATION_NOT_ALLOWED = 190004
} | 定义错误码枚举值。 | | [ArkUI_ScrollSource](#arkui_scrollsource) {
ARKUI_SCROLL_SOURCE_DRAG = 0, ARKUI_SCROLL_SOURCE_FLING, ARKUI_SCROLL_SOURCE_EDGE_EFFECT, ARKUI_SCROLL_SOURCE_OTHER_USER_INPUT,
ARKUI_SCROLL_SOURCE_SCROLL_BAR, ARKUI_SCROLL_SOURCE_SCROLL_BAR_FLING, ARKUI_SCROLL_SOURCE_SCROLLER, ARKUI_SCROLL_SOURCE_ANIMATION
} | 定义滚动来源枚举值。 | | [ArkUI_SafeAreaType](#arkui_safeareatype) { ARKUI_SAFE_AREA_TYPE_SYSTEM = 1, ARKUI_SAFE_AREA_TYPE_CUTOUT = 1 << 1, ARKUI_SAFE_AREA_TYPE_KEYBOARD = 1 << 2 } | 定义扩展安全区域的枚举值。 | | [ArkUI_ListItemGroupArea](#arkui_listitemgrouparea) { ARKUI_LIST_ITEM_GROUP_AREA_OUTSIDE = 0, ARKUI_LIST_ITEM_SWIPE_AREA_NONE = 1, ARKUI_LIST_ITEM_SWIPE_AREA_ITEM = 2, ARKUI_LIST_ITEM_SWIPE_AREA_HEADER = 3, ARKUI_LIST_ITEM_SWIPE_AREA_FOOTER = 4
} | 定义组件区域的枚举值。 | @@ -2684,6 +2684,7 @@ enum ArkUI_ErrorCode | ARKUI_ERROR_CODE_GET_INFO_FAILED = 106201 | 查询路由导航信息失败。
错误码的详细介绍请参见[导航错误码](../apis-arkui/errorcode-router.md#106201-查询路由导航信息失败)。 | | ARKUI_ERROR_CODE_BUFFER_SIZE_ERROR = 106202 | 传入的buffer size异常。
错误码的详细介绍请参见[导航错误码](../apis-arkui/errorcode-router.md#106202-传入的buffer-size异常)。 | | ARKUI_ERROR_CODE_NODE_NOT_ON_MAIN_TREE = 106203 | 传入的节点未挂载到组件树上。
错误码的详细介绍请参见[自定义节点错误码](../apis-arkui/errorcode-node.md)。
起始版本:15 | +| ARKUI_ERROR_CODE_NODE_ON_INVALID_THREAD = 106204 | 此节点未在合法的线程上操作。
**起始版本:** 20 | | ARKUI_ERROR_CODE_FOCUS_NON_FOCUSABLE = 150001 | 当前节点无法获得焦点。
错误码的详细介绍请参见[焦点错误码](../apis-arkui/errorcode-focus.md#150001-节点无法获得焦点)。
起始版本:15 | | ARKUI_ERROR_CODE_FOCUS_NON_FOCUSABLE_ANCESTOR = 150002 | 当前节点对应的祖先节点中存在无法获焦节点。
错误码的详细介绍请参见[焦点错误码](../apis-arkui/errorcode-focus.md#150002-祖先节点无法获得焦点)。
起始版本:15 | | ARKUI_ERROR_CODE_FOCUS_NON_EXISTENT = 150003 | 当前节点不存在。
错误码的详细介绍请参见[焦点错误码](../apis-arkui/errorcode-focus.md#150003-节点不存在)。
起始版本:15 | @@ -3520,6 +3521,7 @@ enum ArkUI_NativeAPIVariantKind | ARKUI_NATIVE_DIALOG | 弹窗相关接口类型,详见<arkui/native_dialog.h>中的结构体类型定义。 | | ARKUI_NATIVE_GESTURE | 手势相关接口类型,详见<arkui/native_gesture.h>中的结构体类型定义。 | | ARKUI_NATIVE_ANIMATE | 动画相关接口类型。详见<arkui/native_animate.h>中的结构体类型定义。 | +| ARKUI_MULTI_THREAD_NATIVE_NODE | 多线程UI组件相关接口类型。详见<arkui/native_node.h>中的结构体类型定义。 | ### ArkUI_NavDestinationState @@ -19570,3 +19572,208 @@ void OH_ArkUI_EmbeddedComponentOption_SetOnTerminated(ArkUI_EmbeddedComponentOpt | option | EmbeddedComponent组件选项的对象的指针。| | code | 被拉起EmbeddedUIExtensionAbility退出时返回的结果码。若Ability通过调用terminateSelfWithResult退出,结果码为Ability设置的值。若Ability通过调用terminateSelf退出,结果码为默认值"0"。| | want | 被拉起EmbeddedUIExtensionAbility退出时返回的数据。| + +### OH_ArkUI_PostAsyncUITask() + +``` +int32_t OH_ArkUI_PostAsyncUITask(ArkUI_ContextHandle context, void* asyncUITaskData, + void (*asyncUITask)(void* asyncUITaskData), void (*onFinish)(void* asyncUITaskData)) +``` +**描述:** + +将UI任务抛到框架提供的非UI线程中执行。 + +适用于UI组件创建并行化场景,开发者可以使用此接口在非UI线程创建UI组件,创建完成后回到UI线程将其挂载到UI树上。 + +**起始版本:** 20 + +**参数:** + +| 名称 | 描述 | +| -------- | -------- | +| uiContext | UI实例对象指针。 | +| asyncUITaskData | 开发者自定义数据指针,作为asyncUITask和onFinish的入参。 | +| asyncUITask| 在非UI线程执行的函数。| +| onFinish | asyncUITask执行完成后,在UI线程执行的函数。 | + +**返回:** + +[ARKUI_ERROR_CODE_NO_ERROR](_ark_u_i___native_module.md#arkui_errorcode) 成功。 +[ARKUI_ERROR_CODE_PARAM_INVALID](_ark_u_i___native_module.md#arkui_errorcode) uiContext或asyncUITask为空指针。 + +**示例代码:** + +``` cpp +struct AsyncData { + ArkUI_NodeHandle parent = nullptr; + ArkUI_NodeHandle child = nullptr; + ArkUI_NativeNodeAPI_1 *multiThreadNodeAPI = nullptr; +}; + +// 组件多线程创建完成后,回到主线程挂载 +void MountNodeTree(void *asyncUITaskData) { + auto parent = asyncData->parent; + auto child = asyncData->child; + multiThreadNodeAPI->addChild(parent, child); + delete asyncData; +} + +// 多线程的组件创建接口 +void CreateNodeTree(void *asyncUITaskData) { + asyncData->child = multiThreadNodeAPI->createNode(ARKUI_NODE_BUTTON); + ArkUI_AttributeItem label_item = { .string = "button" }; + multiThreadNodeAPI->setAttribute(button1, NODE_BUTTON_LABEL, &label_item); +} + +napi_value CreateNodeTreeOnMultiThread(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = { nullptr }; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + ArkUI_ContextHandle contextHandle; + OH_ArkUI_GetContextFromNapiValue(env, args[0], &contextHandle); + ArkUI_NativeNodeAPI_1 *multiThreadNodeAPI = nullptr; + OH_ArkUI_GetModuleInterface(ARKUI_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeAPI); + AsyncData* asyncData = new AsyncData(); + asyncData->parent = multiThreadNodeAPI->createNode(ARKUI_NODE_ROW); + asyncData->multiThreadNodeAPI = multiThreadNodeAPI; + // 在框架提供的线程池中创建UI组件 + OH_ArkUI_PostAsyncUITask(contextHandle, asyncData, CreateNodeTree, MountNodeTree); +} +``` + +### OH_ArkUI_PostUITask() + +``` +int32_t OH_ArkUI_PostUITask(ArkUI_ContextHandle context, void* taskData, void (*task)(void* taskData)) +``` +**描述:** + +将UI任务抛到UI线程中执行。 + +适用于UI组件创建并行化场景,当开发者需要在自己维护的非UI线程中创建UI组件,使用此接口在UI线程将非UI线程创建的组件挂载到UI树上。 + +**起始版本:** 20 + +**参数:** + +| 名称 | 描述 | +| -------- | -------- | +| uiContext | UI实例对象指针。 | +| taskData | 开发者自定义数据指针,作为task的入参。 | +| task | 在UI线程执行的函数。 | + +**返回:** + +[ARKUI_ERROR_CODE_NO_ERROR](_ark_u_i___native_module.md#arkui_errorcode) 成功。 +[ARKUI_ERROR_CODE_PARAM_INVALID](_ark_u_i___native_module.md#arkui_errorcode) uiContext或task为空指针。 + +**示例代码:** + +``` cpp +struct AsyncData { + ArkUI_NodeHandle parent = nullptr; + ArkUI_NodeHandle child = nullptr; + ArkUI_NativeNodeAPI_1 *multiThreadNodeAPI = nullptr; +}; + +// 组件多线程创建完成后,回到主线程挂载 +void MountNodeTree(void *asyncUITaskData) { + auto parent = asyncData->parent; + auto child = asyncData->child; + multiThreadNodeAPI->addChild(parent, child); + delete asyncData; +} + +// 多线程的组件创建接口 +void CreateNodeTree(void *asyncUITaskData) { + asyncData->child = multiThreadNodeAPI->createNode(ARKUI_NODE_BUTTON); + ArkUI_AttributeItem label_item = { .string = "button" }; + multiThreadNodeAPI->setAttribute(button1, NODE_BUTTON_LABEL, &label_item); + OH_ArkUI_PostAsyncUITask(contextHandle, asyncData, MountNodeTree); +} + +napi_value CreateNodeTreeOnMultiThread(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = { nullptr }; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + ArkUI_ContextHandle contextHandle; + OH_ArkUI_GetContextFromNapiValue(env, args[0], &contextHandle); + ArkUI_NativeNodeAPI_1 *multiThreadNodeAPI = nullptr; + OH_ArkUI_GetModuleInterface(ARKUI_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeAPI); + AsyncData* asyncData = new AsyncData(); + asyncData->parent = multiThreadNodeAPI->createNode(ARKUI_NODE_ROW); + asyncData->multiThreadNodeAPI = multiThreadNodeAPI; + // 在开发者维护的非UI线程中创建UI组件 + std::thread t(CreateNodeTree, asyncData); +} +``` + +### OH_ArkUI_PostUITaskAndWait() + +``` +int32_t OH_ArkUI_PostUITaskAndWait(ArkUI_ContextHandle context, void* taskData, void (*task)(void* taskData)) +``` +**描述:** + +将UI任务抛到UI线程中执行,调用此接口的线程阻塞等待UI线程中的UI任务执行完成。 + +适用于UI组件创建并行化场景,当开发者在非UI线程创建组件的过程中需要执行只支持UI线程的业务逻辑时,使用此接口回到UI线程执行业务逻辑,业务完成后继续在非UI线程创建组件。 + +可能导致非UI线程长时间阻塞,不建议频繁使用。 + + +**起始版本:** 20 + +**参数:** + +| 名称 | 描述 | +| -------- | -------- | +| uiContext | UI实例对象指针。 | +| taskData | 开发者自定义数据指针,作为task的入参。 | +| task | 在UI线程执行的函数。 | + +**返回:** + +[ARKUI_ERROR_CODE_NO_ERROR](_ark_u_i___native_module.md#arkui_errorcode) 成功。 +[ARKUI_ERROR_CODE_PARAM_INVALID](_ark_u_i___native_module.md#arkui_errorcode) uiContext或task为空指针。 + +**示例代码:** + +``` cpp +struct AsyncData { + ArkUI_NodeHandle parent = nullptr; + ArkUI_NodeHandle child = nullptr; + ArkUI_NativeNodeAPI_1 *multiThreadNodeAPI = nullptr; +}; + +// 组件多线程创建完成后,回到主线程挂载 +void MountNodeTree(void *asyncUITaskData) { + auto parent = asyncData->parent; + auto child = asyncData->child; + multiThreadNodeAPI->addChild(parent, child); + delete asyncData; +} + +// 多线程的组件创建接口 +void CreateNodeTree(void *asyncUITaskData) { + asyncData->child = multiThreadNodeAPI->createNode(ARKUI_NODE_BUTTON); + ArkUI_AttributeItem label_item = { .string = "button" }; + multiThreadNodeAPI->setAttribute(button1, NODE_BUTTON_LABEL, &label_item); + OH_ArkUI_PostUITaskAndWait(contextHandle, asyncData, MountNodeTree); +} + +napi_value CreateNodeTreeOnMultiThread(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = { nullptr }; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + ArkUI_ContextHandle contextHandle; + OH_ArkUI_GetContextFromNapiValue(env, args[0], &contextHandle); + ArkUI_NativeNodeAPI_1 *multiThreadNodeAPI = nullptr; + OH_ArkUI_GetModuleInterface(ARKUI_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeAPI); + AsyncData* asyncData = new AsyncData(); + asyncData->parent = multiThreadNodeAPI->createNode(ARKUI_NODE_ROW); + asyncData->multiThreadNodeAPI = multiThreadNodeAPI; + // 在开发者维护的非UI线程中创建UI组件 + std::thread t(CreateNodeTree, asyncData); +} +``` diff --git a/zh-cn/application-dev/reference/apis-arkui/native__interface_8h.md b/zh-cn/application-dev/reference/apis-arkui/native__interface_8h.md index 888e6e2b91c70d9936150719dd6f519ec8a22f20..b63e20d6b6e78abc926f1940d1506078a1c1f9ed 100644 --- a/zh-cn/application-dev/reference/apis-arkui/native__interface_8h.md +++ b/zh-cn/application-dev/reference/apis-arkui/native__interface_8h.md @@ -30,7 +30,7 @@ | 名称 | 描述 | | -------- | -------- | -| [ArkUI_NativeAPIVariantKind](_ark_u_i___native_module.md#arkui_nativeapivariantkind) { ARKUI_NATIVE_NODE, ARKUI_NATIVE_DIALOG, ARKUI_NATIVE_GESTURE, ARKUI_NATIVE_ANIMATE } | 定义Native接口集合类型。 | +| [ArkUI_NativeAPIVariantKind](_ark_u_i___native_module.md#arkui_nativeapivariantkind) { ARKUI_NATIVE_NODE, ARKUI_NATIVE_DIALOG, ARKUI_NATIVE_GESTURE, ARKUI_NATIVE_ANIMATE, ARKUI_MULTI_THREAD_NATIVE_NODE } | 定义Native接口集合类型。 | ### 函数 diff --git a/zh-cn/application-dev/reference/apis-arkui/native__node_8h.md b/zh-cn/application-dev/reference/apis-arkui/native__node_8h.md index 4ebd150db90a31334fd6c4aafba252af1f976164..3acc64a43c002f835ee5acc95d8a7cfcdcf3a989 100644 --- a/zh-cn/application-dev/reference/apis-arkui/native__node_8h.md +++ b/zh-cn/application-dev/reference/apis-arkui/native__node_8h.md @@ -158,3 +158,7 @@ NODE_TEXT_AREA_HALF_LEADING = 8025, NODE_TEXT_AREA_KEYBOARD_APPEARANCE = 8026, N | int32_t [OH_ArkUI_NodeUtils_SetCrossLanguageOption](_ark_u_i___native_module.md#oh_arkui_nodeutils_setcrosslanguageoption)([ArkUI_NodeHandle](_ark_u_i___native_module.md#arkui_nodehandle) node, ArkUI_CrossLanguageOption* option) | 设置目标节点跨语言的配置。
**起始版本:** 15 | | int32_t [OH_ArkUI_NodeUtils_GetCrossLanguageOption](_ark_u_i___native_module.md#oh_arkui_nodeutils_getcrosslanguageoption)([ArkUI_NodeHandle](_ark_u_i___native_module.md#arkui_nodehandle) node, ArkUI_CrossLanguageOption* option) | 获取目标节点跨语言的配置。
**起始版本:** 15 | | int32_t [OH_ArkUI_NodeUtils_GetAttachedNodeHandleById](_ark_u_i___native_module.md#oh_arkui_nodeutils_getattachednodehandlebyid)(const char* id, [ArkUI_NodeHandle](_ark_u_i___native_module.md#arkui_nodehandle)* node) | 根据传入的id获取当前节点树上对应的目标节点。
**起始版本:** 15 | +| int32_t [OH_ArkUI_PostAsyncUITask](_ark_u_i___native_module.md#oh_arkui_postasyncuitask)([ArkUI_ContextHandle](_ark_u_i___native_module.md#arkui_contexthandle-12) uiContext, void* asyncUITaskData, void (*asyncUITask)(void* asyncUITaskData), void (*onFinish)(void* asyncUITaskData)) | 将UI任务抛到框架提供的非UI线程中执行。
**起始版本:** 20 | +| int32_t [OH_ArkUI_PostUITask](_ark_u_i___native_module.md#oh_arkui_postuitask)([ArkUI_ContextHandle](_ark_u_i___native_module.md#arkui_contexthandle-12) uiContext, void* taskData, void (*task)(void* taskData)) | 将任务抛到UI线程中执行。
**起始版本:** 20 | +| int32_t [OH_ArkUI_PostUITaskAndWait](_ark_u_i___native_module.md#oh_arkui_postuitaskandwait)([ArkUI_ContextHandle](_ark_u_i___native_module.md#arkui_contexthandle-12) uiContext, void* taskData, void (*task)(void* taskData)) | 将任务抛到UI线程中执行并阻塞等待。
**起始版本:** 20 | + diff --git a/zh-cn/application-dev/ui/figures/build_on_multi_thread.jpg b/zh-cn/application-dev/ui/figures/build_on_multi_thread.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c6c0b2f8911a4735864971567e9fd8817f264303 Binary files /dev/null and b/zh-cn/application-dev/ui/figures/build_on_multi_thread.jpg differ diff --git a/zh-cn/application-dev/ui/ndk-build-on-multi-thread-api.md b/zh-cn/application-dev/ui/ndk-build-on-multi-thread-api.md new file mode 100644 index 0000000000000000000000000000000000000000..ff673294bb38d3d50f4dba549201892a4a2461e2 --- /dev/null +++ b/zh-cn/application-dev/ui/ndk-build-on-multi-thread-api.md @@ -0,0 +1,1487 @@ +# 多线程NDK接口说明 + +为保证接口易用性,多线程Native侧Node接口集合与[ArkUI_NativeNodeAPI_1](../reference/apis-arkui/_ark_u_i___native_node_a_p_i__1.md)声明一致。API集合中[组件创建销毁](#组件创建销毁),[属性读写](#组件属性读写),[事件注册解注册](#组件事件注册解注册),[自定义数据读写](#组件自定义数据读写)和[组件树操作](#组件树操作)等接口支持多线程调用,[组件测算布局](#组件测算布局)接口只支持UI线程调用。 + +## 组件创建销毁 + +| 接口名 | 描述 | 非UI线程调用 | 多线程规格 | +| -------- | ------- | ------- | ------- | +| [ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle)(\* [createNode](#createnode) )([ArkUI_NodeType](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodetype) type) | 基于[ArkUI_NodeType](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodetype)生成对应的节点并返回节点对象指针。 | 支持 | 支持在任意线程调用。 | +| void(\* [disposeNode](#disposenode) )([ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle) node) | 销毁节点指针指向的节点对象。 | 支持 | 在非UI线程操作不符合要求的node接口调用不生效。 | + +## 组件属性读写 + +| 接口名 | 描述 | 非UI线程调用 | 多线程规格 | +| -------- | ------- | ------- | ------- | +| int32_t(\* [setAttribute](#setattribute) )([ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle) node, [ArkUI_NodeAttributeType](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodeattributetype) attribute, const [ArkUI_AttributeItem](_ark_u_i___attribute_item.md) \*item) | 设置node节点的属性。 | 支持 | 在非UI线程操作不符合要求的node返回错误码。 | +| const [ArkUI_AttributeItem](_ark_u_i___attribute_item.md) \*(\* [getAttribute](#getattribute) )([ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle) node, [ArkUI_NodeAttributeType](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodeattributetype) attribute) | 获取node节点的属性。 | 支持 | 在非UI线程操作不符合要求的node返回空指针。 | +| int32_t(\* [resetAttribute](#resetattribute) )([ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle) node, [ArkUI_NodeAttributeType](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodeattributetype) attribute) | 重置node节点的属性为默认值。 | 支持 | 在非UI线程操作不符合要求的node返回错误码。 | +| int32_t(\* [setLengthMetricUnit](#setlengthmetricunit) )([ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle) node, [ArkUI_LengthMetricUnit](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_lengthmetricunit) unit) | 指定node节点的单位。 | 支持 | 在非UI线程操作不符合要求的node返回错误码。 | + +## 组件事件注册解注册 + +| 接口名 | 描述 | 非UI线程调用 | 多线程规格 | +| -------- | ------- | ------- | ------- | +| int32_t(\* [registerNodeEvent](#registernodeevent) )([ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle) node, [ArkUI_NodeEventType](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodeeventtype) eventType, int32_t targetId, void \*userData) | 向node节点注册事件。 | 支持 | 在非UI线程操作不符合要求的node返回错误码。 | +| void(\* [unregisterNodeEvent](#unregisternodeevent) )([ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle) node, [ArkUI_NodeEventType](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodeeventtype) eventType) | node节点解注册事件。 | 支持 | 在非UI线程操作不符合要求的node接口调用无效。 | +| int32_t(\* [registerNodeCustomEvent](#registernodecustomevent) )([ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle) node, [ArkUI_NodeCustomEventType](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodecustomeventtype) eventType, int32_t targetId, void \*userData) | 向node节点注册自定义事件。 | 支持 | 在非UI线程操作不符合要求的node返回错误码。 | +| void(\* [unregisterNodeCustomEvent](#unregisternodecustomevent) )([ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle) node, [ArkUI_NodeCustomEventType](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodecustomeventtype) eventType) | node节点解注册自定义事件。 | 支持 | 在非UI线程操作不符合要求的node接口调用不生效。 | +| int32_t(\* [addNodeEventReceiver](#addnodeeventreceiver) )([ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle) node, void(\*eventReceiver)([ArkUI_NodeEvent](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodeevent-12) \*event)) | 向node节点注册事件回调函数,用于接收该组件产生的组件事件。 | 支持 | 在非UI线程操作不符合要求的node返回错误码。 | +| int32_t(\* [removeNodeEventReceiver](#removenodeeventreceiver) )([ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle) node, void(\*eventReceiver)([ArkUI_NodeEvent](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodeevent-12) \*event)) | 删除node节点上注册的事件回调函数。 | 支持 | 在在非UI线程操作不符合要求的node返回错误码。 | +| int32_t(\* [addNodeCustomEventReceiver](#addnodecustomeventreceiver) )([ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle) node, void(\*eventReceiver)([ArkUI_NodeCustomEvent](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodecustomevent) \*event)) | 向node节点注册自定义事件回调函数,用于接收该组件产生的自定义事件(如布局事件,绘制事件)。 | 支持 | 在非UI线程操作不符合要求的node返回错误码。 | +| int32_t(\* [removeNodeCustomEventReceiver](#removenodecustomeventreceiver) )([ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle) node, void(\*eventReceiver)([ArkUI_NodeCustomEvent](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodecustomevent) \*event)) | 删除node节点上注册的自定义事件回调函数。 | 支持 | 在非UI线程操作不符合要求的node返回错误码。 | +| void(\* [registerNodeEventReceiver](#registernodeeventreceiver) )(void(\*eventReceiver)([ArkUI_NodeEvent](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodeevent-12) \*event)) | 注册节点事件回调统一入口函数。 | 不支持 | 只支持UI线程调用,否则接口调用不生效。 | +| void(\* [unregisterNodeEventReceiver](#unregisternodeeventreceiver) )() | 解注册节点事件回调统一入口函数。 | 不支持 | 只支持UI线程调用,否则接口调用不生效。 | +| void(\* [registerNodeCustomEventReceiver](#registernodecustomeventreceiver) )(void(\*eventReceiver)([ArkUI_NodeCustomEvent](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodecustomevent) \*event)) | 注册节点自定义事件回调统一入口函数。 | 不支持 | 只支持UI线程调用,否则接口调用不生效。 | +| void(\* [unregisterNodeCustomEventReceiver](#unregisternodecustomeventreceiver) )() | 解注册节点自定义事件回调统一入口函数。 | 不支持 | 只支持UI线程调用,否则接口调用不生效。 | + +## 组件树操作 + +| 接口名 | 描述 | 非UI线程调用 | 多线程规格 | +| -------- | ------- | ------- | ------- | +| int32_t(\* [addChild](#addchild) )([ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle) parent, [ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle) child) | 将child节点挂载到parent节点的子节点列表中。 | 支持 | 在非UI线程操作不符合要求的parent返回错误码。 | +| int32_t(\* [removeChild](#removechild) )([ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle) parent, [ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle) child) | 将child节点从parent节点的子节点列表中移除。 | 支持 | 在非UI线程操作不符合要求的parent返回错误码。 | +| int32_t(\* [insertChildAfter](#insertchildafter) )([ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle) parent, [ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle) child, [ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle) sibling) | 将child节点挂载到parent节点的子节点列表中,挂载位置在sibling节点之后。 | 支持 | 在非UI线程操作不符合要求的parent返回错误码。 | +| int32_t(\* [insertChildBefore](#insertchildbefore) )([ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle) parent, [ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle) child, [ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle) sibling) | 将child节点挂载到parent节点的子节点列表中,挂载位置在sibling节点之前。 | 支持 | 在非UI线程操作不符合要求的parent返回错误码。 | +| int32_t(\* [insertChildAt](#insertchildat) )([ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle) parent, [ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle) child, int32_t position) | 将child节点挂载到parent节点的子节点列表中,挂载位置由position指定。 | 支持 | 在非UI线程操作不符合要求的parent返回错误码。 | +| [ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle)(\* [getParent](#getparent) )([ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle) node) | 获取node节点的父节点。 | 支持 | 在非UI线程操作不符合要求的node返回错误码。 | +| int32_t(\* [removeAllChildren](#removeallchildren) )([ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle) parent) | 移除node节点的所有子节点。 | 支持 | 在非UI线程操作不符合要求的parent返回错误码。 | +| uint32_t(\* [getTotalChildCount](#gettotalchildcount) )([ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle) node) | 获取node节点的子节点个数。 | 支持 | 在非UI线程操作不符合要求的node接口返回0。 | +| [ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle)(\* [getChildAt](#getchildat) )([ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle) node, int32_t position) | 获取node节点的子节点指针,位置由position指定。 | 支持 | 在非UI线程操作不符合要求的node接口返回空指针。 | +| [ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle)(\* [getFirstChild](#getfirstchild) )([ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle) node) | 获取node节点的第一个子节点指针。 | 支持 | 在非UI线程操作不符合要求的node接口返回空指针。 | +| [ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle)(\* [getLastChild](#getlastchild) )([ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle) node) | 获取node节点的最后一个子节点指针。 | 支持 | 在非UI线程操作不符合要求的node接口返回空指针。 | +| [ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle)(\* [getPreviousSibling](#getprevioussibling) )([ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle) node) | 获取node节点的上一个兄弟节点指针。 | 支持 | 在非UI线程操作不符合要求的node接口返回空指针。 | +| [ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle)(\* [getNextSibling](#getnextsibling) )([ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle) node) | 获取node节点的下一个兄弟节点指针。 | 支持 | 在非UI线程操作不符合要求的node接口返回空指针。 | + +## 组件自定义数据读写 + +| 接口名 | 描述 | 非UI线程调用 | 多线程规格 | +| -------- | ------- | ------- | ------- | +| int32_t(\* [setUserData](#setuserdata) )([ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle) node, void \*userData) | 在node节点上保存自定义数据。 | 支持 | 在非UI线程操作不符合要求的node接口返回错误码。 | +| void \*(\* [getUserData](#getuserdata) )([ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle) node) | 获取node节点上保存的自定义数据。 | 支持 | 在非UI线程操作不符合要求的node接口返回空指针。 | + +## 组件测算布局 + +| 接口名 | 描述 | 非UI线程调用 | 多线程规格 | +| -------- | ------- | ------- | ------- | +| int32_t(\* [setMeasuredSize](#setmeasuredsize) )([ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle) node, int32_t width, int32_t height) | 在测算回调函数中设置组件测算完成后的宽和高。 | 不支持 | 只支持UI线程调用,否则接口返回错误码。 | +| int32_t(\* [setLayoutPosition](#setlayoutposition) )([ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle) node, int32_t positionX, int32_t positionY) | 在布局回调函数中设置组件的位置。 | 不支持 | 只支持UI线程调用,否则接口返回错误码。 | +| [ArkUI_IntSize](_ark_u_i___int_size.md)(\* [getMeasuredSize](#getmeasuredsize) )([ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle) node) | 获取node节点测算完成后的宽高尺寸。 | 不支持 | 只支持UI线程调用,否则接口返回默认值。 | +| [ArkUI_IntOffset](_ark_u_i___int_offset.md)(\* [getLayoutPosition](#getlayoutposition) )([ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle) node) | 获取node节点布局完成后的位置。 | 不支持 | 只支持UI线程调用,否则接口返回默认值。 | +| int32_t(\* [measureNode](#measurenode) )([ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle) node, [ArkUI_LayoutConstraint](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_layoutconstraint) \*Constraint) | 对node节点进行测算,可以通过getMeasuredSize获取测算后的大小。 | 不支持 | 只支持UI线程调用,否则接口返回错误码。 | +| int32_t(\* [layoutNode](#layoutnode) )([ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle) node, int32_t positionX, int32_t positionY) | 对node节点进行布局并传递该组件相对父组件的期望位置。 | 不支持 | 只支持UI线程调用,否则接口返回错误码。 | +| void(\* [markDirty](#markdirty) )([ArkUI_NodeHandle](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodehandle) node, [ArkUI_NodeDirtyFlag](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodedirtyflag) dirtyFlag) | 强制标记node节点需要重新测算、布局或绘制。 | 不支持 | 只支持UI线程调用,否则接口调用不生效。 | + + +## 接口详细说明 + + +### addChild + +``` +int32_t(* ArkUI_NativeNodeAPI_1::addChild) (ArkUI_NodeHandle parent, ArkUI_NodeHandle child) +``` +**描述:** + +将节点挂载到某个父节点下。 + +在非UI线程调用函数操作已挂载到UI树上的节点时,函数返回错误码。 + +**参数:** + +| 名称 | 描述 | +| -------- | -------- | +| parent | 父节点指针。 | +| child | 子节点指针。 | + +**返回:** + +[ARKUI_ERROR_CODE_NO_ERROR](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)成功。 + +[ARKUI_ERROR_CODE_PARAM_INVALID](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)函数参数异常。 + +[ARKUI_ERROR_CODE_NOT_SUPPORTED_FOR_ARKTS_NODE](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)禁止对BuilderNode生成的节点, 进行设置属性、重置属性、设置事件与新增或修改子节点操作。 + +[ARKUI_ERROR_CODE_ON_INVALID_THREAD](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)禁止在非UI线程调用函数操作已挂载到UI树上的节点。 + +**示例:** +``` +ArkUI_NativeNodeAPI_1 *multiThreadNodeApi = nullptr; +OH_ArkUI_GetModuleInterface(ARKUI_MULTI_THREAD_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeApi); + +auto parent = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); +auto child = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); +multiThreadNodeApi->addChild(parent, child); +``` + +### addNodeCustomEventReceiver + +``` +int32_t(* ArkUI_NativeNodeAPI_1::addNodeCustomEventReceiver) (ArkUI_NodeHandle node, void(*eventReceiver)(ArkUI_NodeCustomEvent *event)) +``` +**描述:** + +在节点上添加自定义事件回调函数,用于接受该节点产生的自定义事件(如布局事件,绘制事件)。 + +不同于registerNodeCustomEventReceiver的全局注册函数,该函数允许在同一个节点上添加多个事件接受器。 + +该函数添加的监听回调函数触发时机会先于registerNodeCustomEventReceiver注册的全局回调函数。 + +避免直接保存ArkUI_NodeCustomEvent对象指针,数据会在回调结束后销毁。 + +在非UI线程调用函数操作已挂载到UI树上的节点时,函数返回错误码。 + +**参数:** + +| 名称 | 描述 | +| -------- | -------- | +| node | 用于添加组件自定义事件回调函数的对象。 | +| eventReceiver | 组件自定义事件回调函数。 | + +**返回:** + +[ARKUI_ERROR_CODE_NO_ERROR](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)成功。 + +[ARKUI_ERROR_CODE_PARAM_INVALID](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)函数参数异常。 + +[ARKUI_ERROR_CODE_ON_INVALID_THREAD](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)禁止在非UI线程调用函数操作已挂载到UI树上的节点。 + +**示例:** +``` +ArkUI_NativeNodeAPI_1 *multiThreadNodeApi = nullptr; +OH_ArkUI_GetModuleInterface(ARKUI_MULTI_THREAD_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeApi); + +auto node = multiThreadNodeApi->createNode(ARKUI_NODE_CUSTOM); +auto receiver = [](ArkUI_NodeCustomEvent *event) {}; +multiThreadNodeApi->addNodeCustomEventReceiver(node, receiver); +``` + +### addNodeEventReceiver + +``` +int32_t(* ArkUI_NativeNodeAPI_1::addNodeEventReceiver) (ArkUI_NodeHandle node, void(*eventReceiver)(ArkUI_NodeEvent *event)) +``` +**描述:** + +在节点上添加节点事件回调函数,用于接受该节点产生的节点事件。 + +不同于registerNodeEventReceiver的全局注册函数,该函数允许在同一个节点上添加多个事件接受器。 + +该函数添加的监听回调函数触发时机会先于registerNodeEventReceiver注册的全局回调函数。 + +避免直接保存ArkUI_NodeEvent对象指针,数据会在回调结束后销毁。 + +在非UI线程调用函数操作已挂载到UI树上的节点时,函数返回错误码。 + +**参数:** + +| 名称 | 描述 | +| -------- | -------- | +| node | 用于添加组件事件回调函数的对象。 | +| eventReceiver | 组件事件回调函数。 | + +**返回:** + +[ARKUI_ERROR_CODE_NO_ERROR](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)成功。 + +[ARKUI_ERROR_CODE_PARAM_INVALID](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)函数参数异常。 + +[ARKUI_ERROR_CODE_ON_INVALID_THREAD](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)禁止在非UI线程调用函数操作已挂载到UI树上的节点。 + +**示例:** +``` +ArkUI_NativeNodeAPI_1 *multiThreadNodeApi = nullptr; +OH_ArkUI_GetModuleInterface(ARKUI_MULTI_THREAD_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeApi); + +auto node = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); +auto receiver = [](ArkUI_NodeEvent *event) {}; +multiThreadNodeApi->addNodeEventReceiver(node, receiver); +``` + + +### createNode + +``` +ArkUI_NodeHandle(* ArkUI_NativeNodeAPI_1::createNode) (ArkUI_NodeType type) +``` +**描述:** + +基于[ArkUI_NodeType](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodetype)生成对应的节点并返回节点对象指针。 + +**参数:** + +| 名称 | 描述 | +| -------- | -------- | +| type | 创建指定类型的UI组件节点。 | + +**返回:** + +返回创建完成的节点操作指针,如果创建失败返回空指针。 + +**示例:** +``` +ArkUI_NativeNodeAPI_1 *multiThreadNodeApi = nullptr; +OH_ArkUI_GetModuleInterface(ARKUI_MULTI_THREAD_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeApi); + +auto node = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); +``` + +### disposeNode + +``` +void(* ArkUI_NativeNodeAPI_1::disposeNode) (ArkUI_NodeHandle node) +``` +**描述:** + +销毁节点指针指向的节点对象。 + +在非UI线程调用函数操作已挂载到UI树的节点时,函数调用不生效。 + +**参数:** + +| 名称 | 描述 | +| -------- | -------- | +| node | 组件节点对象。 | + +**示例:** +``` +ArkUI_NativeNodeAPI_1 *multiThreadNodeApi = nullptr; +OH_ArkUI_GetModuleInterface(ARKUI_MULTI_THREAD_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeApi); + +auto node = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); +multiThreadNodeApi->disposeNode(node); +``` + + +### getAttribute + +``` +const ArkUI_AttributeItem*(* ArkUI_NativeNodeAPI_1::getAttribute) (ArkUI_NodeHandle node, ArkUI_NodeAttributeType attribute) +``` +**描述:** + +属性获取函数。 + +该接口返回的指针是ArkUI框架内部的缓冲区指针,不需要开发者主动调用delete释放内存,但是需要在该函数下一次被调用前使用,否则可能会被其他值所覆盖。 + +在非UI线程调用函数操作已挂载到UI树上的节点时,函数返回空指针。 + +**参数:** + +| 名称 | 描述 | +| -------- | -------- | +| node | 需要获取属性的节点对象。 | +| attribute | 需要获取的属性类型。 | + +**返回:** + +当前属性类型的属性值,失败返回空指针。 + +在非UI线程调用函数操作已挂载到UI树上的节点时,函数返回空指针。 + +**示例:** +``` +ArkUI_NativeNodeAPI_1 *multiThreadNodeApi = nullptr; +OH_ArkUI_GetModuleInterface(ARKUI_MULTI_THREAD_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeApi); + +auto node = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); +auto attributeItem = multiThreadNodeApi->getAttribute(node, NODE_WIDTH); +``` + +### getChildAt + +``` +ArkUI_NodeHandle(* ArkUI_NativeNodeAPI_1::getChildAt) (ArkUI_NodeHandle node, int32_t position) +``` +**描述:** + +获取子节点。 + +在非UI线程调用函数操作已挂载到UI树上的节点时,函数返回空指针。 + +**参数:** + +| 名称 | 描述 | +| -------- | -------- | +| node | 目标节点对象。 | +| position | 子节点的位置。 | + +**返回:** + +返回子节点的指针,如果没有返回空指针。 + +在非UI线程调用函数操作已挂载到UI树上的节点时,函数返回空指针。 + +**示例:** +``` +ArkUI_NativeNodeAPI_1 *multiThreadNodeApi = nullptr; +OH_ArkUI_GetModuleInterface(ARKUI_MULTI_THREAD_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeApi); +auto node = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); +auto node2 = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); +multiThreadNodeApi->addChild(node, node2); + +auto child = multiThreadNodeApi->getChildAt(node, 0); +``` + +### getFirstChild + +``` +ArkUI_NodeHandle(* ArkUI_NativeNodeAPI_1::getFirstChild) (ArkUI_NodeHandle node) +``` +**描述:** + +获取第一个子节点。 + +在非UI线程调用函数操作已挂载到UI树上的节点时,函数返回空指针。 + +**参数:** + +| 名称 | 描述 | +| -------- | -------- | +| node | 目标节点对象。 | + +**返回:** + +返回子节点的指针,如果没有返回空指针。 + +在非UI线程调用函数操作已挂载到UI树上的节点时,函数返回空指针。 + +**示例:** +``` +ArkUI_NativeNodeAPI_1 *multiThreadNodeApi = nullptr; +OH_ArkUI_GetModuleInterface(ARKUI_MULTI_THREAD_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeApi); +auto node = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); +auto node2 = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); +multiThreadNodeApi->addChild(node, node2); + +auto child = multiThreadNodeApi->getFirstChild(node); +``` + +### getLastChild + +``` +ArkUI_NodeHandle(* ArkUI_NativeNodeAPI_1::getLastChild) (ArkUI_NodeHandle node) +``` +**描述:** + +获取最后一个子节点。 + +在非UI线程调用函数操作已挂载到UI树上的节点时,函数返回空指针。 + +**参数:** + +| 名称 | 描述 | +| -------- | -------- | +| node | 目标节点对象。 | + +**返回:** + +返回子节点的指针,如果没有返回空指针。 + +在非UI线程调用函数操作已挂载到UI树上的节点时,函数返回空指针。 + +**示例:** +``` +ArkUI_NativeNodeAPI_1 *multiThreadNodeApi = nullptr; +OH_ArkUI_GetModuleInterface(ARKUI_MULTI_THREAD_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeApi); +auto node = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); +auto node2 = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); +multiThreadNodeApi->addChild(node, node2); + +auto child = multiThreadNodeApi->getLastChild(node); +``` + +### getLayoutPosition + +``` +ArkUI_IntOffset(* ArkUI_NativeNodeAPI_1::getLayoutPosition) (ArkUI_NodeHandle node) +``` +**描述:** + +获取节点布局完成后的位置。 + +在非UI线程调用函数操作已挂载到UI树上的节点时,函数返回ArkUI_IntOffset默认值{0, 0}。 + +**参数:** + +| 名称 | 描述 | +| -------- | -------- | +| node | 目标节点对象。 | + +**返回:** + +[ArkUI_IntOffset](../reference/apis-arkui/_ark_u_i___int_offset.md) 节点的位置。 + +在非UI线程调用函数操作已挂载到UI树上的节点时,函数返回ArkUI_IntOffset默认值{0, 0}。 + +**示例:** +``` +ArkUI_NativeNodeAPI_1 *multiThreadNodeApi = nullptr; +OH_ArkUI_GetModuleInterface(ARKUI_MULTI_THREAD_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeApi); +auto node = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); + +auto layoutPosition = multiThreadNodeApi->getLayoutPosition(node); +``` + + +### getMeasuredSize + +``` +ArkUI_IntSize(* ArkUI_NativeNodeAPI_1::getMeasuredSize) (ArkUI_NodeHandle node) +``` +**描述:** + +获取节点测算完成后的宽高尺寸。 + +在非UI线程调用函数操作已挂载到UI树上的节点时,接口返回ArkUI_IntSize默认值{0, 0}。 + +**参数:** + +| 名称 | 描述 | +| -------- | -------- | +| node | 目标节点对象。 | + +**返回:** + +[ArkUI_IntSize](../reference/apis-arkui/_ark_u_i___int_size.md) 节点的宽高。 + +在非UI线程调用函数操作已挂载到UI树上的节点时,接口返回ArkUI_IntSize默认值{0, 0}。 + +**示例:** +``` +ArkUI_NativeNodeAPI_1 *multiThreadNodeApi = nullptr; +OH_ArkUI_GetModuleInterface(ARKUI_MULTI_THREAD_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeApi); +auto node = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); + +auto layoutPosition = multiThreadNodeApi->getMeasuredSize(node); +``` + +### getNextSibling + +``` +ArkUI_NodeHandle(* ArkUI_NativeNodeAPI_1::getNextSibling) (ArkUI_NodeHandle node) +``` +**描述:** + +获取下一个兄弟节点。 + +在非UI线程调用函数操作已挂载到UI树上的节点时,函数返回空指针。 + +**参数:** + +| 名称 | 描述 | +| -------- | -------- | +| node | 目标节点对象。 | + +**返回:** + +返回节点的指针,如果没有返回空指针。 + +在非UI线程调用函数操作已挂载到UI树上的节点时,函数返回空指针。 + +**示例:** +``` +ArkUI_NativeNodeAPI_1 *multiThreadNodeApi = nullptr; +OH_ArkUI_GetModuleInterface(ARKUI_MULTI_THREAD_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeApi); +auto node = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); +auto node2 = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); +auto node3 = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); +multiThreadNodeApi->addChild(node, node2); +multiThreadNodeApi->addChild(node, node3); + +auto nextSibling = multiThreadNodeApi->getNextSibling(node2); +``` + + +### getParent + +``` +ArkUI_NodeHandle(* ArkUI_NativeNodeAPI_1::getParent) (ArkUI_NodeHandle node) +``` +**描述:** + +获取父节点。 + +在非UI线程调用函数操作已挂载到UI树上的节点时,函数返回空指针。 + +**参数:** + +| 名称 | 描述 | +| -------- | -------- | +| node | 目标节点对象。 | + +**返回:** + +返回节点的指针,如果没有返回空指针。 + +在非UI线程调用函数操作已挂载到UI树上的节点时,函数返回空指针。 + +**示例:** +``` +ArkUI_NativeNodeAPI_1 *multiThreadNodeApi = nullptr; +OH_ArkUI_GetModuleInterface(ARKUI_MULTI_THREAD_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeApi); +auto node = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); +auto node2 = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); +multiThreadNodeApi->addChild(node, node2); + +auto parent = multiThreadNodeApi->getNextSibling(node2); +``` + +### getPreviousSibling + +``` +ArkUI_NodeHandle(* ArkUI_NativeNodeAPI_1::getPreviousSibling) (ArkUI_NodeHandle node) +``` +**描述:** + +获取上一个兄弟节点。 + +在非UI线程调用函数操作已挂载到UI树上的node节点时,函数返回空指针。 + +**参数:** + +| 名称 | 描述 | +| -------- | -------- | +| node | 目标节点对象。 | + +**返回:** + +返回组件的指针,如果没有返回空指针。 + +在非UI线程调用函数操作已挂载到UI树上的node节点时,函数返回空指针。 + +**示例:** +``` +ArkUI_NativeNodeAPI_1 *multiThreadNodeApi = nullptr; +OH_ArkUI_GetModuleInterface(ARKUI_MULTI_THREAD_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeApi); +auto node = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); +auto node2 = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); +auto node3 = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); +multiThreadNodeApi->addChild(node, node2); +multiThreadNodeApi->addChild(node, node3); + +auto previousSibling = multiThreadNodeApi->getPreviousSibling(node3); +``` + + +### getTotalChildCount + +``` +uint32_t(* ArkUI_NativeNodeAPI_1::getTotalChildCount) (ArkUI_NodeHandle node) +``` +**描述:** + +获取子节点的个数。 + +在非UI线程调用函数操作已挂载到UI树上的节点时,函数返回0。 + +**参数:** + +| 名称 | 描述 | +| -------- | -------- | +| node | 目标节点对象。 | + +**返回:** + +子节点的个数, 如果没有返回0。 + +在非UI线程调用函数操作已挂载到UI树上的节点时,函数返回0。 + +**示例:** +``` +ArkUI_NativeNodeAPI_1 *multiThreadNodeApi = nullptr; +OH_ArkUI_GetModuleInterface(ARKUI_MULTI_THREAD_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeApi); +auto node = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); +auto node2 = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); +multiThreadNodeApi->addChild(node, node2); + +auto count = multiThreadNodeApi->getTotalChildCount(node); +``` + + +### getUserData + +``` +void*(* ArkUI_NativeNodeAPI_1::getUserData) (ArkUI_NodeHandle node) +``` +**描述:** + +获取在节点上保存的自定义数据。 + +在非UI线程调用函数操作已挂载到UI树上的节点时,接口返回空指针。 + +**参数:** + +| 名称 | 描述 | +| -------- | -------- | +| node | 保存了自定义数据的节点对象。 | + +**返回:** + +自定义数据。 + +在非UI线程调用函数操作已挂载到UI树上的节点时,接口返回空指针。 + +**示例:** +``` +ArkUI_NativeNodeAPI_1 *multiThreadNodeApi = nullptr; +OH_ArkUI_GetModuleInterface(ARKUI_MULTI_THREAD_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeApi); +auto node = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); +char* data = "user data"; +multiThreadNodeApi->setUserData(node, data); + +auto userData = multiThreadNodeApi->getUserData(node); +``` + + +### insertChildAfter + +``` +int32_t(* ArkUI_NativeNodeAPI_1::insertChildAfter) (ArkUI_NodeHandle parent, ArkUI_NodeHandle child, ArkUI_NodeHandle sibling) +``` +**描述:** + +将节点挂载到某个父节点之下,挂载位置在sibling节点之后。 + +在非UI线程调用函数操作已挂载到UI树上的节点时,函数返回错误码。 + +**参数:** + +| 名称 | 描述 | +| -------- | -------- | +| parent | 父节点指针。 | +| child | 子节点指针。 | +| sibling | 前一个兄弟节点指针,如果为空则插入位置在最后面。 | + +**返回:** + +[ARKUI_ERROR_CODE_NO_ERROR](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)成功。 + +[ARKUI_ERROR_CODE_PARAM_INVALID](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)函数参数异常。 + +[ARKUI_ERROR_CODE_NOT_SUPPORTED_FOR_ARKTS_NODE](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)禁止对BuilderNode生成的节点,进行设置属性、重置属性、设置事件与新增或修改子节点操作。 + +[ARKUI_ERROR_CODE_ON_INVALID_THREAD](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)禁止在非UI线程调用函数操作已挂载到UI树上的节点。 + +**示例:** +``` +ArkUI_NativeNodeAPI_1 *multiThreadNodeApi = nullptr; +OH_ArkUI_GetModuleInterface(ARKUI_MULTI_THREAD_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeApi); +auto node = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); +auto node2 = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); +multiThreadNodeApi->addChild(node, node2); + +auto child = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); +multiThreadNodeApi->insertChildAfter(node, child, node2); +``` + + +### insertChildAt + +``` +int32_t(* ArkUI_NativeNodeAPI_1::insertChildAt) (ArkUI_NodeHandle parent, ArkUI_NodeHandle child, int32_t position) +``` +**描述:** + +将节点挂载到某个父节点之下,挂载位置由position指定。 + +在非UI线程调用函数操作已挂载到UI树上的节点时,函数返回错误码。 + +**参数:** + +| 名称 | 描述 | +| -------- | -------- | +| parent | 父节点指针。 | +| child | 子节点指针。 | +| position | 插入位置,如果插入位置为负数或者不存在,则默认插入位置在最后面。 | + +**返回:** + +[ARKUI_ERROR_CODE_NO_ERROR](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)成功。 + +[ARKUI_ERROR_CODE_PARAM_INVALID](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)函数参数异常。 + +[ARKUI_ERROR_CODE_NOT_SUPPORTED_FOR_ARKTS_NODE](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)禁止对BuilderNode生成的节点, 进行设置属性、重置属性、设置事件与新增或修改子节点操作。 + +[ARKUI_ERROR_CODE_ON_INVALID_THREAD](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)禁止在非UI线程调用函数操作已挂载到UI树上的节点。 + +**示例:** +``` +ArkUI_NativeNodeAPI_1 *multiThreadNodeApi = nullptr; +OH_ArkUI_GetModuleInterface(ARKUI_MULTI_THREAD_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeApi); +auto node = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); + +auto child = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); +multiThreadNodeApi->insertChildAt(node, child, 0); +``` + +### insertChildBefore + +``` +int32_t(* ArkUI_NativeNodeAPI_1::insertChildBefore) (ArkUI_NodeHandle parent, ArkUI_NodeHandle child, ArkUI_NodeHandle sibling) +``` +**描述:** + +将节点挂载到某个父节点之下,挂载位置在sibling节点之前。 + +在非UI线程调用函数操作已挂载到UI树上的节点时,函数返回错误码。 + +**参数:** + +| 名称 | 描述 | +| -------- | -------- | +| parent | 父节点指针。 | +| child | 子节点指针。 | +| sibling | 后一个兄弟节点指针,如果为空则插入位置在最后面。 | + +**返回:** + +[ARKUI_ERROR_CODE_NO_ERROR](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)成功。 + +[ARKUI_ERROR_CODE_PARAM_INVALID](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)函数参数异常。 + +[ARKUI_ERROR_CODE_NOT_SUPPORTED_FOR_ARKTS_NODE](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)禁止对BuilderNode生成的节点, 进行设置属性、重置属性、设置事件与新增或修改子节点操作。 + +[ARKUI_ERROR_CODE_ON_INVALID_THREAD](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)禁止在非UI线程调用函数操作已挂载到UI树上的节点。 + +**示例:** +``` +ArkUI_NativeNodeAPI_1 *multiThreadNodeApi = nullptr; +OH_ArkUI_GetModuleInterface(ARKUI_MULTI_THREAD_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeApi); +auto node = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); +auto node2 = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); +multiThreadNodeApi->addChild(node, node2); + +auto child = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); +multiThreadNodeApi->insertChildBefore(node, child, node2); +``` + + +### layoutNode + +``` +int32_t(* ArkUI_NativeNodeAPI_1::layoutNode) (ArkUI_NodeHandle node, int32_t positionX, int32_t positionY) +``` +**描述:** + +对特定节点进行布局并传递该节点相对父节点的期望位置。 + +在非UI线程调用此函数返回错误码。 + +**参数:** + +| 名称 | 描述 | +| -------- | -------- | +| node | 目标节点对象。 | +| positionX | x轴坐标。 | +| positionY | y轴坐标。 | + +**返回:** + +[ARKUI_ERROR_CODE_NO_ERROR](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)成功。 + +[ARKUI_ERROR_CODE_PARAM_INVALID](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)函数参数异常。 + +[ARKUI_ERROR_CODE_ON_INVALID_THREAD](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)禁止在非UI线程调用函数。 + +**示例:** +``` +ArkUI_NativeNodeAPI_1 *multiThreadNodeApi = nullptr; +OH_ArkUI_GetModuleInterface(ARKUI_MULTI_THREAD_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeApi); +auto node = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); + +multiThreadNodeApi->layoutNode(node, 0, 0); +``` + +### markDirty + +``` +void(* ArkUI_NativeNodeAPI_1::markDirty) (ArkUI_NodeHandle node, ArkUI_NodeDirtyFlag dirtyFlag) +``` +**描述:** + +强制标记当前节点需要重新测算,布局或者绘制。 + +系统属性设置更新场景下ArkUI框架会自动标记脏区并重新执行测算,布局或者绘制,不需要开发者主动调用该函数。 + +在非UI线程调用此函数不生效。 + +**参数:** + +| 名称 | 描述 | +| -------- | -------- | +| node | 需要标记脏区的节点对象。 | +| dirtyFlag | 脏区类型。 | + +**示例:** +``` +ArkUI_NativeNodeAPI_1 *multiThreadNodeApi = nullptr; +OH_ArkUI_GetModuleInterface(ARKUI_MULTI_THREAD_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeApi); +auto node = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); + +multiThreadNodeApi->markDirty(node, NODE_NEED_MEASURE); +``` + +### measureNode + +``` +int32_t(* ArkUI_NativeNodeAPI_1::measureNode) (ArkUI_NodeHandle node, ArkUI_LayoutConstraint *Constraint) +``` +**描述:** + +对特定节点进行测算,可以通过getMeasuredSize接口获取测算后的大小。 + +在非UI线程调用此函数返回错误码。 + +**参数:** + +| 名称 | 描述 | +| -------- | -------- | +| node | 目标节点对象。 | +| Constraint | 约束尺寸。 | + +**返回:** + +[ARKUI_ERROR_CODE_NO_ERROR](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)成功。 + +[ARKUI_ERROR_CODE_PARAM_INVALID](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)函数参数异常。 + +[ARKUI_ERROR_CODE_ON_INVALID_THREAD](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)禁止在非UI线程调用函数。 + +**示例:** +``` +ArkUI_NativeNodeAPI_1 *multiThreadNodeApi = nullptr; +OH_ArkUI_GetModuleInterface(ARKUI_MULTI_THREAD_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeApi); +auto node = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); + +ArkUI_LayoutConstraint *constraint = nullptr; +multiThreadNodeApi->measureNode(node, constraint); +``` + +### registerNodeCustomEvent + +``` +int32_t(* ArkUI_NativeNodeAPI_1::registerNodeCustomEvent) (ArkUI_NodeHandle node, ArkUI_NodeCustomEventType eventType, int32_t targetId, void *userData) +``` +**描述:** + +注册自定义节点事件函数。事件触发时通过registerNodeCustomEventReceiver注册的自定义事件入口函数返回。 + +在非UI线程调用函数操作已挂载到UI树上的节点时,函数返回错误码。 + +**参数:** + +| 名称 | 描述 | +| -------- | -------- | +| node | 需要注册事件的节点对象。 | +| eventType | 需要注册的事件类型。 | +| targetId | 自定义事件ID,当事件触发时在回调参数[ArkUI_NodeCustomEvent](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodecustomevent) 中携带回来。 | +| userData | 自定义事件参数,当事件触发时在回调参数[ArkUI_NodeCustomEvent](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodecustomevent) 中携带回来。 | + +**返回:** + +[ARKUI_ERROR_CODE_NO_ERROR](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)成功。 + +[ARKUI_ERROR_CODE_PARAM_INVALID](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)函数参数异常。 + +[ARKUI_ERROR_CODE_ATTRIBUTE_OR_EVENT_NOT_SUPPORTED](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)系统中未找到Native接口的动态实现库。 + +[ARKUI_ERROR_CODE_ON_INVALID_THREAD](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)禁止在非UI线程调用函数操作已挂载到UI树上的节点。 + +**示例:** +``` +ArkUI_NativeNodeAPI_1 *multiThreadNodeApi = nullptr; +OH_ArkUI_GetModuleInterface(ARKUI_MULTI_THREAD_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeApi); +auto node = multiThreadNodeApi->createNode(ARKUI_NODE_CUSTOM); + +multiThreadNodeApi->registerNodeCustomEvent(node, ARKUI_NODE_CUSTOM_EVENT_ON_MEASURE, 0, nullptr); +``` + + +### registerNodeCustomEventReceiver + +``` +void(* ArkUI_NativeNodeAPI_1::registerNodeCustomEventReceiver) (void(*eventReceiver)(ArkUI_NodeCustomEvent *event)) +``` +**描述:** + +注册自定义节点事件回调统一入口函数。 + +ArkUI框架会统一收集过程中产生的自定义组件事件并通过注册的registerNodeCustomEventReceiver函数回调给开发者。 + +重复调用时会覆盖前一次注册的函数。 + +避免直接保存ArkUI_NodeCustomEvent对象指针,数据会在回调结束后销毁。 + +如果需要和组件实例绑定,可以使用addNodeCustomEventReceiver函数接口。 + +在非UI线程调用此函数不生效。 + +**参数:** + +| 名称 | 描述 | +| -------- | -------- | +| eventReceiver | 事件回调统一入口函数。 | + +**示例:** +``` +ArkUI_NativeNodeAPI_1 *multiThreadNodeApi = nullptr; +OH_ArkUI_GetModuleInterface(ARKUI_MULTI_THREAD_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeApi); + +auto receiver = [](ArkUI_NodeCustomEvent *event){}; +multiThreadNodeApi->registerNodeCustomEventReceiver(receiver); +``` + + +### registerNodeEvent + +``` +int32_t(* ArkUI_NativeNodeAPI_1::registerNodeEvent) (ArkUI_NodeHandle node, ArkUI_NodeEventType eventType, int32_t targetId, void *userData) +``` +**描述:** + +注册节点事件函数。 + +在非UI线程调用函数操作已挂载到UI树上的节点时,函数返回错误码。 + +**参数:** + +| 名称 | 描述 | +| -------- | -------- | +| node | 需要注册事件的节点对象。 | +| eventType | 需要注册的事件类型。 | +| targetId | 自定义事件ID,当事件触发时在回调参数[ArkUI_NodeEvent](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodeevent-12) 中携带回来。 | +| userData | 自定义事件参数,当事件触发时在回调参数[ArkUI_NodeEvent](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_nodeevent-12) 中携带回来。 | + +**返回:** + +[ARKUI_ERROR_CODE_NO_ERROR](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)成功。 + +[ARKUI_ERROR_CODE_PARAM_INVALID](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)函数参数异常。 + +[ARKUI_ERROR_CODE_ATTRIBUTE_OR_EVENT_NOT_SUPPORTED](../reference/apis-arkui/_ark_u_i___native_module. +md#arkui_errorcode)系统中未找到Native接口的动态实现库。 + +[ARKUI_ERROR_CODE_NOT_SUPPORTED_FOR_ARKTS_NODE](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)禁止对BuilderNode生成的节点, 进行设置属性、重置属性、设置事件与新增或修改子节点操作。 + +[ARKUI_ERROR_CODE_ON_INVALID_THREAD](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)禁止在非UI线程操作已挂载到UI树上的节点。 + +**示例:** +``` +ArkUI_NativeNodeAPI_1 *multiThreadNodeApi = nullptr; +OH_ArkUI_GetModuleInterface(ARKUI_MULTI_THREAD_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeApi); +auto node = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); + +multiThreadNodeApi->registerNodeEvent(node, NODE_TOUCH_EVENT, 0, nullptr); +``` + +### registerNodeEventReceiver + +``` +void(* ArkUI_NativeNodeAPI_1::registerNodeEventReceiver) (void(*eventReceiver)(ArkUI_NodeEvent *event)) +``` +**描述:** + +注册事件回调统一入口函数。 + +ArkUI框架会统一收集过程中产生的组件事件并通过注册的eventReceiver函数回调给开发者。 + +重复调用时会覆盖前一次注册的函数。 + +避免直接保存ArkUI_NodeEvent对象指针,数据会在回调结束后销毁。 + +如果需要和组件实例绑定,可以使用addNodeEventReceiver函数接口。 + +在非UI线程调用此函数不生效。 + +**参数:** + +| 名称 | 描述 | +| -------- | -------- | +| eventReceiver | 事件回调统一入口函数。 | + +**示例:** +``` +ArkUI_NativeNodeAPI_1 *multiThreadNodeApi = nullptr; +OH_ArkUI_GetModuleInterface(ARKUI_MULTI_THREAD_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeApi); + +auto receiver = [](ArkUI_NodeEvent *event){}; +multiThreadNodeApi->registerNodeEventReceiver(receiver); +``` + +### removeAllChildren + +``` +int32_t(* ArkUI_NativeNodeAPI_1::removeAllChildren) (ArkUI_NodeHandle parent) +``` +**描述:** + +从目标节点上移除所有子节点。 + +在非UI线程调用函数操作已挂载到UI树上的节点时,函数返回错误码。 + +**参数:** + +| 名称 | 描述 | +| -------- | -------- | +| parent | 目标节点对象。 | + +**返回:** + +[ARKUI_ERROR_CODE_NO_ERROR](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)成功。 + +[ARKUI_ERROR_CODE_PARAM_INVALID](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)函数参数异常。 + +[ARKUI_ERROR_CODE_ON_INVALID_THREAD](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)禁止在非UI线程调用函数操作已挂载到UI树上的节点。 + +**示例:** +``` +ArkUI_NativeNodeAPI_1 *multiThreadNodeApi = nullptr; +OH_ArkUI_GetModuleInterface(ARKUI_MULTI_THREAD_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeApi); +auto node = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); +auto node2 = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); +multiThreadNodeApi->addChild(node, node2); + +multiThreadNodeApi->removeAllChildren(node); +``` + +### unregisterNodeCustomEventReceiver + +``` +void(* ArkUI_NativeNodeAPI_1::unregisterNodeCustomEventReceiver) () +``` +**描述:** + +解注册节点自定义事件回调统一入口函数。 + +在非UI线程调用函数不生效。 + +**示例:** +``` +ArkUI_NativeNodeAPI_1 *multiThreadNodeApi = nullptr; +OH_ArkUI_GetModuleInterface(ARKUI_MULTI_THREAD_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeApi); +auto receiver = [](ArkUI_NodeCustomEvent *event){}; +multiThreadNodeApi->registerNodeCustomEventReceiver(receiver); + +multiThreadNodeApi->unregisterNodeCustomEventReceiver(); +``` + + +### unregisterNodeEventReceiver + +``` +void(* ArkUI_NativeNodeAPI_1::unregisterNodeEventReceiver) () +``` +**描述:** + +解注册事件回调统一入口函数。 + +在非UI线程调用函数不生效。 + +**示例:** +``` +ArkUI_NativeNodeAPI_1 *multiThreadNodeApi = nullptr; +OH_ArkUI_GetModuleInterface(ARKUI_MULTI_THREAD_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeApi); +auto receiver = [](ArkUI_NodeEvent *event){}; +multiThreadNodeApi->registerNodeEventReceiver(receiver); + +multiThreadNodeApi->unregisterNodeEventReceiver(); +``` + +### removeChild + +``` +int32_t(* ArkUI_NativeNodeAPI_1::removeChild) (ArkUI_NodeHandle parent, ArkUI_NodeHandle child) +``` +**描述:** + +将节点从父节点中移除。 + +在非UI线程调用函数操作已挂载到UI树上的节点时,函数返回错误码。 + +**参数:** + +| 名称 | 描述 | +| -------- | -------- | +| parent | 父节点对象。 | +| child | 子节点对象。 | + +**返回:** + +[ARKUI_ERROR_CODE_NO_ERROR](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)成功。 + +[ARKUI_ERROR_CODE_PARAM_INVALID](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)函数参数异常。 + +[ARKUI_ERROR_CODE_NOT_SUPPORTED_FOR_ARKTS_NODE](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)禁止对BuilderNode生成的节点, 进行设置属性、重置属性、设置事件与新增或修改子节点操作。 + +[ARKUI_ERROR_CODE_ON_INVALID_THREAD](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)禁止在非UI线程调用函数操作已挂载到UI树上的节点。 + +**示例:** +``` +ArkUI_NativeNodeAPI_1 *multiThreadNodeApi = nullptr; +OH_ArkUI_GetModuleInterface(ARKUI_MULTI_THREAD_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeApi); +auto node = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); +auto node2 = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); +multiThreadNodeApi->addChild(node, node2); + +multiThreadNodeApi->removeChild(node, node2); +``` + +### removeNodeCustomEventReceiver + +``` +int32_t(* ArkUI_NativeNodeAPI_1::removeNodeCustomEventReceiver) (ArkUI_NodeHandle node, void(*eventReceiver)(ArkUI_NodeCustomEvent *event)) +``` +**描述:** + +删除节点上注册的自定义事件回调函数。 + +在非UI线程调用函数操作已挂载到UI树上的节点时,函数返回错误码。 + +**参数:** + +| 名称 | 描述 | +| -------- | -------- | +| node | 用于删除节点自定义事件回调函数的节点对象。 | +| eventReceiver | 待删除的节点自定义事件回调函数。 | + +**返回:** + +[ARKUI_ERROR_CODE_NO_ERROR](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)成功。 + +[ARKUI_ERROR_CODE_PARAM_INVALID](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)函数参数异常。 + +[ARKUI_ERROR_CODE_ON_INVALID_THREAD](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)禁止在非UI线程调用函数操作已挂载到UI树上的节点。 + +**示例:** +``` +ArkUI_NativeNodeAPI_1 *multiThreadNodeApi = nullptr; +OH_ArkUI_GetModuleInterface(ARKUI_MULTI_THREAD_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeApi); +auto node = multiThreadNodeApi->createNode(ARKUI_NODE_CUSTOM); +auto receiver = [](ArkUI_NodeCustomEvent *event) {}; +multiThreadNodeApi->addNodeCustomEventReceiver(node, receiver); + +multiThreadNodeApi->removeNodeCustomEventReceiver(node, receiver); +``` + + +### removeNodeEventReceiver + +``` +int32_t(* ArkUI_NativeNodeAPI_1::removeNodeEventReceiver) (ArkUI_NodeHandle node, void(*eventReceiver)(ArkUI_NodeEvent *event)) +``` +**描述:** + +删除节点上注册的节点事件回调函数。 + +在非UI线程调用函数操作已挂载到UI树上的节点时,函数返回错误码。 + +**参数:** + +| 名称 | 描述 | +| -------- | -------- | +| node | 用于删除节点事件回调函数的节点对象。 | +| eventReceiver | 待删除的节点事件回调函数。 | + +**返回:** + +[ARKUI_ERROR_CODE_NO_ERROR](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)成功。 + +[ARKUI_ERROR_CODE_PARAM_INVALID](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)函数参数异常。 + +[ARKUI_ERROR_CODE_ON_INVALID_THREAD](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)禁止在非UI线程调用函数操作已挂载到UI树上的节点。 + +**示例:** +``` +ArkUI_NativeNodeAPI_1 *multiThreadNodeApi = nullptr; +OH_ArkUI_GetModuleInterface(ARKUI_MULTI_THREAD_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeApi); +auto node = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); +auto receiver = [](ArkUI_NodeEvent *event) {}; +multiThreadNodeApi->addNodeEventReceiver(node, receiver); + +multiThreadNodeApi->removeNodeEventReceiver(node, receiver); +``` + + +### resetAttribute + +``` +int32_t(* ArkUI_NativeNodeAPI_1::resetAttribute) (ArkUI_NodeHandle node, ArkUI_NodeAttributeType attribute) +``` +**描述:** + +重置属性函数。 + +在非UI线程调用函数操作已挂载到UI树上的节点时,函数返回错误码。 + +**参数:** + +| 名称 | 描述 | +| -------- | -------- | +| node | 需要重置属性的节点对象。 | +| attribute | 需要重置的属性类型。 | + +**返回:** + +[ARKUI_ERROR_CODE_NO_ERROR](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)成功。 + +[ARKUI_ERROR_CODE_PARAM_INVALID](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)函数参数异常。 + +[ARKUI_ERROR_CODE_ATTRIBUTE_OR_EVENT_NOT_SUPPORTED](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)系统中未找到Native接口的动态实现库。 +[ARKUI_ERROR_CODE_NOT_SUPPORTED_FOR_ARKTS_NODE](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)禁止对BuilderNode生成的节点, 进行设置属性、重置属性、设置事件与新增或修改子节点操作。 + +[ARKUI_ERROR_CODE_ON_INVALID_THREAD](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)禁止在非UI线程调用函数操作已挂载到UI树上的节点。 + +**示例:** +``` +ArkUI_NativeNodeAPI_1 *multiThreadNodeApi = nullptr; +OH_ArkUI_GetModuleInterface(ARKUI_MULTI_THREAD_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeApi); +auto node = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); +ArkUI_NumberValue value[] = {{.f32 = 100}}; +ArkUI_AttributeItem item = {value, 1}; +multiThreadNodeApi->setAttribute(node, NODE_WIDTH, &item); + +auto attributeItem = multiThreadNodeApi->resetAttribute(node, NODE_WIDTH); +``` + + +### setAttribute + +``` +int32_t(* ArkUI_NativeNodeAPI_1::setAttribute) (ArkUI_NodeHandle node, ArkUI_NodeAttributeType attribute, const ArkUI_AttributeItem *item) +``` +**描述:** + +属性设置函数。 + +在非UI线程调用函数操作已挂载到UI树上的节点时,函数返回错误码。 + +**参数:** + +| 名称 | 描述 | +| -------- | -------- | +| node | 需要设置属性的节点对象。 | +| attribute | 需要设置的属性类型。 | +| item | 需要设置的属性值。 | + +**返回:** + +[ARKUI_ERROR_CODE_NO_ERROR](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)成功。 + +[ARKUI_ERROR_CODE_PARAM_INVALID](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)函数参数异常。 + +[ARKUI_ERROR_CODE_ATTRIBUTE_OR_EVENT_NOT_SUPPORTED](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)系统中未找到Native接口的动态实现库。 + +[ARKUI_ERROR_CODE_NOT_SUPPORTED_FOR_ARKTS_NODE](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)禁止对BuilderNode生成的节点, 进行设置属性、重置属性、设置事件与新增或修改子节点操作。 + +[ARKUI_ERROR_CODE_ON_INVALID_THREAD](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)禁止在非UI线程调用函数操作已挂载到UI树上的节点。 + +**示例:** +``` +ArkUI_NativeNodeAPI_1 *multiThreadNodeApi = nullptr; +OH_ArkUI_GetModuleInterface(ARKUI_MULTI_THREAD_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeApi); +auto node = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); + +ArkUI_NumberValue value[] = {{.f32 = 100}}; +ArkUI_AttributeItem item = {value, 1}; +multiThreadNodeApi->setAttribute(node, NODE_WIDTH, &item); +``` + +### setLayoutPosition + +``` +int32_t(* ArkUI_NativeNodeAPI_1::setLayoutPosition) (ArkUI_NodeHandle node, int32_t positionX, int32_t positionY) +``` +**描述:** + +在布局回调函数中设置节点的位置。 + +在非UI线程调用函数返回错误码。 + +**参数:** + +| 名称 | 描述 | +| -------- | -------- | +| node | 目标节点对象。 | +| positionX | x轴坐标。 | +| positionY | y轴坐标。 | + +**返回:** + +[ARKUI_ERROR_CODE_NO_ERROR](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)成功。 + +[ARKUI_ERROR_CODE_PARAM_INVALID](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)函数参数异常。 + +[ARKUI_ERROR_CODE_ON_INVALID_THREAD](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)禁止在非UI线程调用函数。 + +**示例:** +``` +ArkUI_NativeNodeAPI_1 *multiThreadNodeApi = nullptr; +OH_ArkUI_GetModuleInterface(ARKUI_MULTI_THREAD_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeApi); +auto node = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); + +multiThreadNodeApi->setLayoutPosition(node, 0, 0); +``` + +### setLengthMetricUnit + +``` +int32_t(* ArkUI_NativeNodeAPI_1::setLengthMetricUnit) (ArkUI_NodeHandle node, ArkUI_LengthMetricUnit unit) +``` +**描述:** + +指定节点的单位。 + +在非UI线程调用函数返回错误码。 + +**参数:** + +| 名称 | 描述 | +| -------- | -------- | +| node | 用于指定单位的节点。 | +| unit | 单位类型[ArkUI_LengthMetricUnit](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_lengthmetricunit),默认为 ARKUI_LENGTH_METRIC_UNIT_DEFAULT。 | + +**返回:** + +[ARKUI_ERROR_CODE_NO_ERROR](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)成功。 + +[ARKUI_ERROR_CODE_PARAM_INVALID](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)函数参数异常。 + +[ARKUI_ERROR_CODE_ON_INVALID_THREAD](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)禁止在非UI线程调用函数操作已挂载到UI树上的节点。 + +**示例:** +``` +ArkUI_NativeNodeAPI_1 *multiThreadNodeApi = nullptr; +OH_ArkUI_GetModuleInterface(ARKUI_MULTI_THREAD_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeApi); +auto node = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); + +multiThreadNodeApi->setLengthMetricUnit(node, ARKUI_LENGTH_METRIC_UNIT_VP); +``` + +### setMeasuredSize + +``` +int32_t(* ArkUI_NativeNodeAPI_1::setMeasuredSize) (ArkUI_NodeHandle node, int32_t width, int32_t height) +``` +**描述:** + +在测算回调函数中设置节点测算完成后的宽和高。 + +在非UI线程调用函数返回错误码。 + +**参数:** + +| 名称 | 描述 | +| -------- | -------- | +| node | 目标节点对象。 | +| width | 设置的宽。 | +| height | 设置的高。 | + +**返回:** + +[ARKUI_ERROR_CODE_NO_ERROR](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)成功。 + +[ARKUI_ERROR_CODE_PARAM_INVALID](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)函数参数异常。 + +[ARKUI_ERROR_CODE_ON_INVALID_THREAD](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)禁止在非UI线程调用此函数。 + +**示例:** +``` +ArkUI_NativeNodeAPI_1 *multiThreadNodeApi = nullptr; +OH_ArkUI_GetModuleInterface(ARKUI_MULTI_THREAD_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeApi); +auto node = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); + +multiThreadNodeApi->setMeasuredSize(node, 100, 100); +``` + +### setUserData + +``` +int32_t(* ArkUI_NativeNodeAPI_1::setUserData) (ArkUI_NodeHandle node, void *userData) +``` +**描述:** + +在节点上保存自定义数据。 + +在非UI线程调用函数操作已挂载到UI树上的节点时,函数返回错误码。 + +**参数:** + +| 名称 | 描述 | +| -------- | -------- | +| node | 用于保存自定义数据的节点。 | +| userData | 要保存的自定义数据。 | + +**返回:** + +[ARKUI_ERROR_CODE_NO_ERROR](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)成功。 + +[ARKUI_ERROR_CODE_PARAM_INVALID](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)函数参数异常。 + +[ARKUI_ERROR_CODE_ON_INVALID_THREAD](../reference/apis-arkui/_ark_u_i___native_module.md#arkui_errorcode)禁止在非UI线程调用函数操作已挂载到UI树上的节点。 + +**示例:** +``` +ArkUI_NativeNodeAPI_1 *multiThreadNodeApi = nullptr; +OH_ArkUI_GetModuleInterface(ARKUI_MULTI_THREAD_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeApi); +auto node = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); + +char* data = "user data"; +multiThreadNodeApi->setUserData(node, data); +``` + +### unregisterNodeCustomEvent + +``` +void(* ArkUI_NativeNodeAPI_1::unregisterNodeCustomEvent) (ArkUI_NodeHandle node, ArkUI_NodeCustomEventType eventType) +``` +**描述:** + +解注册节点自定义事件函数。 + +在非UI线程调用函数操作已挂载到UI树上的节点时,函数不生效。 + +**参数:** + +| 名称 | 描述 | +| -------- | -------- | +| node | 需要解注册事件的节点对象。 | +| eventType | 需要解注册的事件类型。 | + +**示例:** +``` +ArkUI_NativeNodeAPI_1 *multiThreadNodeApi = nullptr; +OH_ArkUI_GetModuleInterface(ARKUI_MULTI_THREAD_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeApi); +auto node = multiThreadNodeApi->createNode(ARKUI_NODE_CUSTOM); +multiThreadNodeApi->registerNodeCustomEvent(node, ARKUI_NODE_CUSTOM_EVENT_ON_MEASURE, 0, nullptr); + +multiThreadNodeApi->unregisterNodeCustomEvent(node, ARKUI_NODE_CUSTOM_EVENT_ON_MEASURE); +``` + +### unregisterNodeEvent + +``` +void(* ArkUI_NativeNodeAPI_1::unregisterNodeEvent) (ArkUI_NodeHandle node, ArkUI_NodeEventType eventType) +``` +**描述:** + +解注册节点事件函数。 + +在非UI线程调用函数操作已挂载到UI树上的节点时,函数不生效。 + +**参数:** + +| 名称 | 描述 | +| -------- | -------- | +| node | 需要解注册事件的节点对象。 | +| eventType | 需要解注册的事件类型。 | + +**示例:** +``` +ArkUI_NativeNodeAPI_1 *multiThreadNodeApi = nullptr; +OH_ArkUI_GetModuleInterface(ARKUI_MULTI_THREAD_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeApi); +auto node = multiThreadNodeApi->createNode(ARKUI_NODE_STACK); +multiThreadNodeApi->registerNodeEvent(node, NODE_TOUCH_EVENT, 0, nullptr); + +multiThreadNodeApi->unregisterNodeEvent(node, NODE_TOUCH_EVENT); +``` \ No newline at end of file diff --git a/zh-cn/application-dev/ui/ndk-build-on-multi-thread.md b/zh-cn/application-dev/ui/ndk-build-on-multi-thread.md new file mode 100644 index 0000000000000000000000000000000000000000..3e4d70e5fbd91e9a591a4ab8ae7f6f76350b8cad --- /dev/null +++ b/zh-cn/application-dev/ui/ndk-build-on-multi-thread.md @@ -0,0 +1,352 @@ +# NDK支持多线程创建组件 +在多线程环境中使用NKD创建UI组件的开发指南 + +## 概述 + +在旧版NDK中,组件的创建与初始化必须在应用程序主线程中执行。这导致开发者在集成时,需要将任务切换回主线程,不仅增加调用代码的复杂度,也限制了组件构造过程的灵活性与性能。 + +随着用户界面日益复杂,页面中可能同时存在大量动态生成的UI组件,这类任务堆积在单一主线程中执行,通常导致启动缓慢、动画掉帧以及界面卡顿,直接影响用户体验。 + +针对这些问题,**新版API引入了完整的多线程支持**,为开发者带来了以下实质性提升: + +- **彻底简化调用流程** 开发者无需手动切换线程或通过任务队列将组件创建任务转回主线程,可以在自己的框架线程中直接调用组件创建接口,减少上下文切换与潜在的竞态问题,简化框架与应用之间的交互逻辑。 + +- **性能与体验大幅优化** 多线程能力允许组件创建与初始化任务并行执行,能充分利用设备多核CPU,在页面启动与界面构造阶段减少总体耗时。主线程则专注动画渲染与用户输入,确保界面流畅与交互及时。 + +- **为未来拓展奠定坚实基础** 多线程支持不仅解决当前性能瓶颈,还为未来引入复杂、高负载的界面组件提供可扩展空间,帮助开发者在设计时拥有更大的灵活度与掌控力,为持续提升用户体验创造条件。 + +通过这次升级,开发者能专注于自身逻辑实现,无需关注并发与线程切换等底层细节。在更大的任务量与复杂场景下,开发者将获得更加可预测、高性能的界面创建体验。 + +## 使用场景 + +- 调用 `OH_ArkUI_GetModuleInterface`,入参传入 `ARKUI_MULTI_THREAD_NATIVE_NODE` 获取支持多线程调用的NDK接口集合。例如: + + ```cpp + ArkUI_NativeNodeAPI_1 *multiThreadNodeAPI = nullptr; + OH_ArkUI_GetModuleInterface(ARKUI_MULTI_THREAD_NATIVE_NODE, ArkUI_NativeNodeAPI_1, multiThreadNodeAPI); + ``` + + 多线程接口详情请参考[多线程NDK接口说明](./ndk-build-on-multi-thread-api.md)。 + +- 使用[OH_ArkUI_PostAsyncUITask](../reference/apis-arkui/_ark_u_i___native_module.md#oh_arkui_postasyncuitask)接口将任务调度到系统线程池中执行. + +- 当开发者需要在自己维护的非UI线程中创建UI组件时,使用[OH_ArkUI_PostUITask](../reference/apis-arkui/_ark_u_i___native_module.md#oh_arkui_postuitask)接口将组件挂载到UI树的任务提交到UI线程执行。 + +- 另提供[OH_ArkUI_PostUITaskAndWait](../reference/apis-arkui/_ark_u_i___native_module.md#oh_arkui_postuitaskandwait)接口将组件挂载到UI树的任务提交到UI线程执行后,此时调用线程阻塞等待UI线程任务结束。此接口可能导致接口调用线程长时间阻塞,不推荐频繁使用。 + +## 调用规范与线程安全 + +- 多线程接口规范请参考[多线程NDK接口说明](./ndk-build-on-multi-thread-api.md)。调用接口时必须检查返回值,如果在非UI线程中调用不支持的接口,将返回错误码。 + +- 尽管我们提供了线程安全的组件创建与属性设置接口,单个组件内部仍然不是线程安全的。请避免在多个线程中同时操作同一组件或同一颗组建树,否则可能出现不可预测的结果。 + +- 多线程接口中,组件有以下两种状态: + + - **Free(游离状态):** 组件未挂载到主树,不参与UI流水线,属性可安全更新。 + - **Attached(已挂载状态):** 组件已挂载,交由UI流水线管理,属性更新必须在UI线程中调用,否则将返回错误码。 + +## 示例 + +以下是接口使用示例。为简化编程和工程管理,在开始编写并行化组件创建代码前,请先参考[接入ArkTS页面](ndk-access-the-arkts-page.md)指导文档,在native侧使用面向对象的方式对将ArkUI_NodeHandle封装为ArkUINode对象。 + +```ts +// index.ets +import { NodeContent } from '@kit.ArkUI'; +import entry from 'libentry.so'; + +@Component +struct CAPIComponent { + private rootSlot = new NodeContent(); + + aboutToAppear(): void { + // 调用Native接口进行组件创建 + entry.CreateNodeTreeOnMultiThread(this.rootSlot, this.getUIContext()); + } + + aboutToDisappear(): void { + // 释放已创建的Native组件 + entry.DisposeNodeTreeOnMultiThread(this.rootSlot); + } + + build() { + Column() { + // Native组件挂载点 + ContentSlot(this.rootSlot) + } + } +} + +@Entry +@Component +struct Index { + @State isShow: boolean = false; + @State message: string = "CreateNodeTree"; + + build() { + Flex() { + Column() { + Text('CreateNodeTreeOnMultiThread') + .fontSize(18) + .fontWeight(FontWeight.Bold) + Button(this.message) + .onClick(() => { + this.isShow = !this.isShow; + if (this.isShow) { + this.message = "DisposeNodeTree" + } else { + this.message = "CreateNodeTree" + } + }) + if (this.isShow) { + CAPIComponent() + } + } + } + } +} + +``` + +```cpp +// NativeModule.h +#ifndef MYAPPLICATION_NATIVEMODULE_H +#define MYAPPLICATION_NATIVEMODULE_H + +#include +#include +#include + +namespace NativeModule { + +class NativeModuleInstance { +public: + static NativeModuleInstance *GetInstance() { + static NativeModuleInstance instance; + return &instance; + } + + NativeModuleInstance() { + // 获取多线程NDK接口的函数指针结构体对象,用于后续操作。 + OH_ArkUI_GetModuleInterface(ARKUI_MULTI_THREAD_NATIVE_NODE, ArkUI_NativeNodeAPI_1, arkUINativeNodeApi_); + assert(arkUINativeNodeApi_); + } + // 暴露给其他模块使用。 + ArkUI_NativeNodeAPI_1 *GetNativeNodeAPI() { return arkUINativeNodeApi_; } + +private: + ArkUI_NativeNodeAPI_1 *arkUINativeNodeApi_ = nullptr; +}; +} // namespace NativeModule + +#endif // MYAPPLICATION_NATIVEMODULE_H +``` + +```cpp +// CreateNode.h +#ifndef MYAPPLICATION_CREATENODE_H +#define MYAPPLICATION_CREATENODE_H + +#include "common/ArkUINode.h" + +#include + +namespace NativeModule { +class ArkUIButtonNode: public ArkUINode { +public: + ArkUIButtonNode() : + ArkUINode(NativeModuleInstance::GetInstance()->GetNativeNodeAPI()->createNode(ARKUI_NODE_BUTTON)) {} + int32_t SetLabel(ArkUI_AttributeItem& label_item) { + return nativeModule_->setAttribute(handle_, NODE_BUTTON_LABEL, &label_item); + } +}; + +class ArkUIRowNode: public ArkUINode { +public: + ArkUIRowNode() : + ArkUINode(NativeModuleInstance::GetInstance()->GetNativeNodeAPI()->createNode(ARKUI_NODE_ROW)) {} +}; + +class ArkUIScrollNode: public ArkUINode { +public: + ArkUIScrollNode() : + ArkUINode(NativeModuleInstance::GetInstance()->GetNativeNodeAPI()->createNode(ARKUI_NODE_SCROLL)) {} +}; + +class ArkUIColumnNode: public ArkUINode { +public: + ArkUIColumnNode() : + ArkUINode(NativeModuleInstance::GetInstance()->GetNativeNodeAPI()->createNode(ARKUI_NODE_COLUMN)) {} +}; + +napi_value DisposeNodeTreeOnMultiThread(napi_env env, napi_callback_info info); +napi_value CreateNodeTreeOnMultiThread(napi_env env, napi_callback_info info); +} // namespace NativeModule + +#endif //MYAPPLICATION_CREATENODE_H +``` + + +```cpp +// CreateNode.cpp +#include "node/CreateNode.h" + +#include +#include +#include +#include + +namespace NativeModule { +#define CHILD_NODE_TREE_NUMBER 10 //多线程创建组件树的数量 +struct AsyncData { + napi_env env; + std::shared_ptr parent = nullptr; + std::shared_ptr child = nullptr; +}; + +// 保存ArkTs侧NodeContent指针与Native侧节点树根节点的对应关系。 +std::map> g_nodeMap; + +//多线程创建组件 +void CreateNodeTree(void *asyncUITaskData) { + auto asyncData = static_cast(asyncUITaskData); + if (!asyncData) { + return; + } + auto rowNode = std::make_shared(); + asyncData->child = rowNode; + + auto buttonNode1 = std::make_shared(); + ArkUI_AttributeItem label_item = { .string = "button1" }; + int32_t result = buttonNode1->SetLabel(label_item); + if (result != ARKUI_ERROR_CODE_NO_ERROR) { + OH_LOG_ERROR(LOG_APP, "Button SetLabel Failed %{public}d", result); + } + + auto buttonNode2 = std::make_shared(); + ArkUI_AttributeItem label_item2 = { .string = "button2" }; + result = buttonNode2->SetLabel(label_item2); + if (result != ARKUI_ERROR_CODE_NO_ERROR) { + OH_LOG_ERROR(LOG_APP, "Button SetLabel Failed %{public}d", result); + } + + rowNode->AddChild(buttonNode1); + rowNode->AddChild(buttonNode2); +} + +// 组件多线程创建完成后,回到UI线程挂载到UI树上 +void MountNodeTree(void *asyncUITaskData) { + auto asyncData = static_cast(asyncUITaskData); + if (!asyncData) { + return; + } + auto parent = asyncData->parent; + auto child = asyncData->child; + parent->AddChild(child); + delete asyncData; +} + +napi_value CreateNodeTreeOnMultiThread(napi_env env, napi_callback_info info) { + size_t argc = 2; + napi_value args[2] = { nullptr, nullptr }; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + + ArkUI_NodeContentHandle contentHandle; + int32_t result = OH_ArkUI_GetNodeContentFromNapiValue(env, args[0], &contentHandle); + if (result != ARKUI_ERROR_CODE_NO_ERROR) { + OH_LOG_ERROR(LOG_APP, "OH_ArkUI_GetNodeContentFromNapiValue Failed %{public}d", result); + return nullptr; + } + ArkUI_ContextHandle contextHandle; + result = OH_ArkUI_GetContextFromNapiValue(env, args[1], &contextHandle); + if (result != ARKUI_ERROR_CODE_NO_ERROR) { + OH_LOG_ERROR(LOG_APP, "OH_ArkUI_GetContextFromNapiValue Failed %{public}d", result); + return nullptr; + } + + auto scrollNode = std::make_shared(); + result = OH_ArkUI_NodeContent_AddNode(contentHandle, scrollNode->GetHandle()); + if (result != ARKUI_ERROR_CODE_NO_ERROR) { + OH_LOG_ERROR(LOG_APP, "OH_ArkUI_NodeContent_AddNode Failed %{public}d", result); + return nullptr; + } + g_nodeMap[contentHandle] = scrollNode; + + auto columnNode = std::make_shared(); + scrollNode->AddChild(columnNode); + for (int i = 0; i < CHILD_NODE_TREE_NUMBER; i++) { + //UI线程创建子树根节点,保证scroll的子节点顺序 + auto columnItem = std::make_shared(); + columnNode->AddChild(columnItem); + AsyncData* asyncData = new AsyncData(); + asyncData->parent = columnItem; + // 在非UI线程创建组件树,创建完成后回到主线程挂载到主树上 + result = OH_ArkUI_PostAsyncUITask(contextHandle, asyncData, CreateNodeTree, MountNodeTree); + if (result != ARKUI_ERROR_CODE_NO_ERROR) { + OH_LOG_ERROR(LOG_APP, "OH_ArkUI_PostAsyncUITask Failed %{public}d", result); + delete asyncData; + } + } + return nullptr; +} + +napi_value DisposeNodeTreeOnMultiThread(napi_env env, napi_callback_info info) +{ + size_t argc = 1; + napi_value args[1] = { nullptr }; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + + ArkUI_NodeContentHandle contentHandle; + int32_t result = OH_ArkUI_GetNodeContentFromNapiValue(env, args[0], &contentHandle); + if (result != ARKUI_ERROR_CODE_NO_ERROR) { + OH_LOG_ERROR(LOG_APP, "OH_ArkUI_GetNodeContentFromNapiValue Failed %{public}d", result); + return nullptr; + } + + auto it = g_nodeMap.find(contentHandle); + if (it == g_nodeMap.end()) { + return nullptr; + } + auto rootNode = it->second; + result = OH_ArkUI_NodeContent_RemoveNode(contentHandle, rootNode->GetHandle()); + if (result != ARKUI_ERROR_CODE_NO_ERROR) { + OH_LOG_ERROR(LOG_APP, "OH_ArkUI_NodeContent_RemoveNode Failed %{public}d", result); + return nullptr; + } + g_nodeMap.erase(contentHandle); + return nullptr; +} +} // namespace NativeModule +``` + + + + +## 错误与异常处理 + +- 在非UI线程中调用不支持多线程的接口将返回错误码。 +- 挂载到UI主树后,非UI线程调用组件接口将返回错误码。 +- 在Native节点下树前,必须先卸载嵌套的ArkTs节点,以避免在非UI线程中遍历节点树时访问ArkTS节点导致崩溃。 + +框架将打印如下日志提示: + +``` +CheckIsThreadSafeNodeTree failed. thread safe node tree contains unsafe node: ${nodeid} +``` + +## 迁移指南 + +1. 将原有接口集合 Tag 从 `ARKUI_NATIVE_NODE` 修改为 `ARKUI_MULTI_THREAD_NATIVE_NODE` 即可获得多线程能力,接口与参数保持一致: + + ```c + ArkUI_NativeNodeAPI_1 *nodeAPI = nullptr; + OH_ArkUI_GetModuleInterface(ARKUI_MULTI_THREAD_NATIVE_NODE, ArkUI_NativeNodeAPI_1, nodeAPI); + ``` + +2. 建议将原先在UI线程中执行的组件创建任务拆分成更细粒度任务,分派给不同工作线程执行,以减少主线程阻塞,提高页面启动与更新流畅度。 + +3. 预先在后台线程中创建常用组件树,为性能敏感场景提供更好的用户体验。 + +## 最佳实践 +通过以下的一个例子,我们将展示如何通过多线程的Native接口来实现并行化创建组建,最终提升用户体验。 + +[最佳实践源码地址](https://gitee.com/openharmony/applications_app_samples/tree/master/code/UI/NdkBuildOnMultiThread/README.md) \ No newline at end of file diff --git a/zh-cn/application-dev/website.md b/zh-cn/application-dev/website.md index 10d0cd480867ca30709289df83c07cf00f9a1ea2..082852ba10b574e74a5a5084f8ecae7163701677 100644 --- a/zh-cn/application-dev/website.md +++ b/zh-cn/application-dev/website.md @@ -606,6 +606,7 @@ - [查询和操作自定义节点](ui/ndk-node-query-operate.md) - [通过EmbeddedComponent拉起EmbeddedUIExtensionAbility](ui/ndk-embedded-component.md) - [在NDK中保证多实例场景功能正常](ui/ndk-scope-task.md) + - [NDK支持多线程创建组件](ui/ndk-build-on-multi-thread.md) - UI开发 (兼容JS的类Web开发范式) - [UI开发 (兼容JS的类Web开发范式)概述](ui/ui-js-overview.md) - 框架说明