diff --git a/code/UI/NdkBuildOnMultiThread/.gitignore b/code/UI/NdkBuildOnMultiThread/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..d2ff20141ceed86d87c0ea5d99481973005bab2b
--- /dev/null
+++ b/code/UI/NdkBuildOnMultiThread/.gitignore
@@ -0,0 +1,12 @@
+/node_modules
+/oh_modules
+/local.properties
+/.idea
+**/build
+/.hvigor
+.cxx
+/.clangd
+/.clang-format
+/.clang-tidy
+**/.test
+/.appanalyzer
\ No newline at end of file
diff --git a/code/UI/NdkBuildOnMultiThread/AppScope/app.json5 b/code/UI/NdkBuildOnMultiThread/AppScope/app.json5
new file mode 100644
index 0000000000000000000000000000000000000000..30162cae2c5ec8aca41c97cf696805785601cf3f
--- /dev/null
+++ b/code/UI/NdkBuildOnMultiThread/AppScope/app.json5
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+{
+ "app": {
+ "bundleName": "com.samples.NdkBuildOnMultiThread",
+ "vendor": "example",
+ "versionCode": 1000000,
+ "versionName": "1.0.0",
+ "icon": "$media:layered_image",
+ "label": "$string:app_name"
+ }
+}
diff --git a/code/UI/NdkBuildOnMultiThread/AppScope/resources/base/element/string.json b/code/UI/NdkBuildOnMultiThread/AppScope/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..d71e5ead1ce20b4ac3384d18e6d104f1ea4d83b4
--- /dev/null
+++ b/code/UI/NdkBuildOnMultiThread/AppScope/resources/base/element/string.json
@@ -0,0 +1,8 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "MyApplication"
+ }
+ ]
+}
diff --git a/code/UI/NdkBuildOnMultiThread/AppScope/resources/base/media/background.png b/code/UI/NdkBuildOnMultiThread/AppScope/resources/base/media/background.png
new file mode 100644
index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f
Binary files /dev/null and b/code/UI/NdkBuildOnMultiThread/AppScope/resources/base/media/background.png differ
diff --git a/code/UI/NdkBuildOnMultiThread/AppScope/resources/base/media/foreground.png b/code/UI/NdkBuildOnMultiThread/AppScope/resources/base/media/foreground.png
new file mode 100644
index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f
Binary files /dev/null and b/code/UI/NdkBuildOnMultiThread/AppScope/resources/base/media/foreground.png differ
diff --git a/code/UI/NdkBuildOnMultiThread/AppScope/resources/base/media/layered_image.json b/code/UI/NdkBuildOnMultiThread/AppScope/resources/base/media/layered_image.json
new file mode 100644
index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a
--- /dev/null
+++ b/code/UI/NdkBuildOnMultiThread/AppScope/resources/base/media/layered_image.json
@@ -0,0 +1,7 @@
+{
+ "layered-image":
+ {
+ "background" : "$media:background",
+ "foreground" : "$media:foreground"
+ }
+}
\ No newline at end of file
diff --git a/code/UI/NdkBuildOnMultiThread/README.md b/code/UI/NdkBuildOnMultiThread/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..a1c07d7ea0cf2d2eec81165437e619e694f656bf
--- /dev/null
+++ b/code/UI/NdkBuildOnMultiThread/README.md
@@ -0,0 +1,219 @@
+# 使用NDK多线程创建UI组件
+
+### 介绍
+
+本示例介绍如何使用多线程NDK接口在非UI线程创建UI组件,从而优化组件创建耗时和响应时延。
+
+### 效果图预览
+
+
+
+
+
+
+
+**使用说明**
+
+1. 点击CreatePageOnMultiThread按钮,触发多线程创建UI页面;
+2. 点击CreatePageOnUIThread按钮,触发在UI线程创建UI页面。
+
+### 实现思路
+
+场景一:点击CreatePageOnMultiThread按钮,跳转到多线程创建的UI页面,页面内的UI组件在非UI线程创建;
+
+场景二:点击CreatePageOnUIThread按钮,跳转到UI线程创建的UI页面,页面内的UI组件在UI线程创建。
+
+1. CAPIComponent自定义组件用于挂载通过NDK创建的组件树。源码参考[Page.ets](./entry/src/main/ets/pages/Page.ets),根据isOnUIThread的状态分别调用CreateNodeTreeOnUIThread在UI线程创建组件和CreateNodeTreeOnMultiThread在多线程创建组件。
+```ts
+import { NodeContent, router } from '@kit.ArkUI';
+import entry from 'libentry.so';
+
+@Component
+struct CAPIComponent {
+ private rootSlot = new NodeContent();
+ @State isOnUIThread: boolean = false;
+
+ aboutToAppear(): void {
+ if (this.isOnUIThread) {
+ // 调用C-API接口在UI线程创建组件
+ entry.CreateNodeTreeOnUIThread(this.rootSlot, this.getUIContext());
+ } else {
+ // 调用C-API接口多线程创建组件
+ entry.CreateNodeTreeOnMultiThread(this.rootSlot, this.getUIContext());
+ }
+ }
+
+ aboutToDisappear(): void {
+ // 释放已创建的C-API组件
+ entry.DisposeNodeTree(this.rootSlot);
+ }
+
+ build() {
+ Column() {
+ // C-API组件挂载点
+ ContentSlot(this.rootSlot)
+ }
+ .width('100%')
+ }
+}
+```
+2. CreateNodeTreeOnMultiThread是对ArkTs暴露的NDK接口,此接口负责多线程创建UI组件。示例中把页面中的每个卡片拆分为一个子任务,分别调用OH_ArkUI_PostAsyncUITask接口在非UI线程创建卡片对应的UI组件树。源码参考[NodeCreator.cpp](./entry/src/main/cpp/node/NodeCreator.cpp)
+```cpp
+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();
+ scrollNode->SetScrollBarDisplayMode(ARKUI_SCROLL_BAR_DISPLAY_MODE_OFF);
+ 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 (int32_t i=0;i();
+ columnItem->SetMargin(8,0,8,0);
+ columnNode->AddChild(columnItem);
+ AsyncData* asyncData = new AsyncData();
+ asyncData->parent = columnItem;
+ asyncData->cardInfo = g_cardTypeInfos[i];
+ // 在非UI线程创建组件树,创建完成后回到主线程挂载到主树上
+ result = OH_ArkUI_PostAsyncUITask(contextHandle, asyncData, CreateCardNodeTree, MountNodeTree);
+ if (result != ARKUI_ERROR_CODE_NO_ERROR) {
+ OH_LOG_ERROR(LOG_APP, "OH_ArkUI_PostAsyncUITask Failed %{public}d", result);
+ delete asyncData;
+ }
+ }
+ return nullptr;
+}
+```
+
+3. CreateCardNodeTree会在非UI线程被调用,根据卡片类型创建对应的UI组件树并设置属性。源码参考[NodeCreator.cpp](./entry/src/main/cpp/node/NodeCreator.cpp)
+
+```cpp
+void CreateCardNodeTree(void *asyncUITaskData) {
+ auto asyncData = static_cast(asyncUITaskData);
+ if (!asyncData) {
+ return;
+ }
+
+ if (asyncData->cardInfo.type == "App") {
+ AppCardInfo info = asyncData->cardInfo.appCardInfo;
+ asyncData->child = CreateAppCard(info);
+ } else if (asyncData->cardInfo.type == "Service") {
+ ServiceCardInfo info = asyncData->cardInfo.serviceCardInfo;;
+ asyncData->child = CreateServiceCard(info);
+ }
+}
+```
+
+4. CreateCardNodeTree执行完成后,MountNodeTree会在UI线程被调用,将子线程创建好的UI组件树挂载到UI主树上,使其可以在页面上显示出来。源码参考[NodeCreator.cpp](./entry/src/main/cpp/node/NodeCreator.cpp)
+
+```cpp
+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;
+}
+```
+
+### 性能对比
+
+本示例使用了多线程NDK接口在非UI线程创建UI组件,减少了UI线程组件创建布局耗时,优化了页面跳转响应时延。
+
+- 使用UI线程创建UI组件
+
+
+
+- 使用多线程创建UI组件
+
+
+
+| | UI线程创建 | 多线程创建 | 优化比例 |
+| -------- | -------- | -------- | -------- |
+| UI线程组件创建耗时 | 41.3ms | 5.6ms | 86.4% |
+| UI线程组件创建布局耗时 | 157.7ms | 129.9ms | 17.5% |
+| 响应时延 | 216.4ms | 56.2ms | 74.0% |
+
+### 工程结构&模块类型
+
+ ```
+ |entry/src/main/cpp
+ | |---card
+ | | |---CardCreator.cpp // UI卡片创建器实现类
+ | | |---CardCreator.h // UI卡片创建器声明
+ | |---common
+ | | |---ArkUIBaseNode.h // NativeNode封装类,实现组件树操作
+ | | |---ArkUINode.h // 派生ArkUIBaseNode类,实现属性设置操作
+ | | |---NativeModule.h // NDK接口集合获取类
+ | |---data
+ | | |---MockData.h // 定义UI卡片内容数据
+ | |---node
+ | | |---NodeCreator.cpp // UI组件树创建器实现
+ | | |---NodeCreator.h // UI组件树创建器声明
+ | | |---TypedArkUINode.h // 不同类型UI组件封装类
+ |entry/src/main/ets
+ | |---entryablity
+ | | |---EntryAbility.ts // 程序入口类
+ | |---pages
+ | | |---Index.ets // 首页
+ | | |---Page.ets // NDK组件页面
+ ```
+
+### 参考资料
+
+[NDK支持多线程创建组件](https://docs.openharmony.cn/pages/v5.0/zh-cn/application-dev/ui/ndk-build-on-multi-thread.md)
+
+[多线程NDK接口说明](https://docs.openharmony.cn/pages/v5.0/zh-cn/application-dev/ui/ndk-build-on-multi-thread-api.md)
+
+### 相关权限
+
+不涉及。
+
+### 依赖
+
+不涉及。
+
+### 约束与限制
+
+1.本示例仅支持标准系统上运行。
+
+2.本示例为Stage模型,支持API20版本SDK,SDK版本号(API Version 20 Release)。
+
+3.本示例需要使用DevEco Studio版本号(DevEco Studio 5.0.0 Release)及以上版本才可编译运行。
+
+### 下载
+
+如需单独下载本工程,执行如下命令:
+
+```shell
+git init
+git config core.sparsecheckout true
+echo code/UI/NdkBuildOnMultiThread/ > .git/info/sparse-checkout
+git remote add origin https://gitee.com/openharmony/applications_app_samples.git
+git pull origin master
\ No newline at end of file
diff --git a/code/UI/NdkBuildOnMultiThread/build-profile.json5 b/code/UI/NdkBuildOnMultiThread/build-profile.json5
new file mode 100644
index 0000000000000000000000000000000000000000..0a9a0f05c71cbefa5bf8073ed263bc05b4bd05c2
--- /dev/null
+++ b/code/UI/NdkBuildOnMultiThread/build-profile.json5
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+{
+ "app": {
+ "signingConfigs": [
+ ],
+ "products": [
+ {
+ "name": "default",
+ "signingConfig": "default",
+ "targetSdkVersion": 20,
+ "compatibleSdkVersion": 20,
+ "compileSdkVersion": 20,
+ "runtimeOS": "OpenHarmony",
+ "buildOption": {
+ "strictMode": {
+ "caseSensitiveCheck": true
+ }
+ }
+ }
+ ],
+ "buildModeSet": [
+ {
+ "name": "debug",
+ },
+ {
+ "name": "release"
+ }
+ ]
+ },
+ "modules": [
+ {
+ "name": "entry",
+ "srcPath": "./entry",
+ "targets": [
+ {
+ "name": "default",
+ "applyToProducts": [
+ "default"
+ ]
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/code/UI/NdkBuildOnMultiThread/code-linter.json5 b/code/UI/NdkBuildOnMultiThread/code-linter.json5
new file mode 100644
index 0000000000000000000000000000000000000000..ed05653cca31b61d64cf6471529eaf50d4f70709
--- /dev/null
+++ b/code/UI/NdkBuildOnMultiThread/code-linter.json5
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+{
+ "files": [
+ "**/*.ets"
+ ],
+ "ignore": [
+ "**/src/ohosTest/**/*",
+ "**/src/test/**/*",
+ "**/src/mock/**/*",
+ "**/node_modules/**/*",
+ "**/oh_modules/**/*",
+ "**/build/**/*",
+ "**/.preview/**/*"
+ ],
+ "ruleSet": [
+ "plugin:@performance/recommended",
+ "plugin:@typescript-eslint/recommended"
+ ],
+ "rules": {
+ "@security/no-unsafe-aes": "error",
+ "@security/no-unsafe-hash": "error",
+ "@security/no-unsafe-mac": "warn",
+ "@security/no-unsafe-dh": "error",
+ "@security/no-unsafe-dsa": "error",
+ "@security/no-unsafe-ecdsa": "error",
+ "@security/no-unsafe-rsa-encrypt": "error",
+ "@security/no-unsafe-rsa-sign": "error",
+ "@security/no-unsafe-rsa-key": "error",
+ "@security/no-unsafe-dsa-key": "error",
+ "@security/no-unsafe-dh-key": "error",
+ "@security/no-unsafe-3des": "error"
+ }
+}
\ No newline at end of file
diff --git a/code/UI/NdkBuildOnMultiThread/entry/.gitignore b/code/UI/NdkBuildOnMultiThread/entry/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..e2713a2779c5a3e0eb879efe6115455592caeea5
--- /dev/null
+++ b/code/UI/NdkBuildOnMultiThread/entry/.gitignore
@@ -0,0 +1,6 @@
+/node_modules
+/oh_modules
+/.preview
+/build
+/.cxx
+/.test
\ No newline at end of file
diff --git a/code/UI/NdkBuildOnMultiThread/entry/build-profile.json5 b/code/UI/NdkBuildOnMultiThread/entry/build-profile.json5
new file mode 100644
index 0000000000000000000000000000000000000000..e058834e4086ef915c4695d303a1b910a1929bd0
--- /dev/null
+++ b/code/UI/NdkBuildOnMultiThread/entry/build-profile.json5
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+{
+ "apiType": "stageMode",
+ "buildOption": {
+ "externalNativeOptions": {
+ "path": "./src/main/cpp/CMakeLists.txt",
+ "arguments": "",
+ "cppFlags": "",
+ "abiFilters": ["armeabi-v7a", "arm64-v8a", "x86_64"]
+ }
+ },
+ "buildOptionSet": [
+ {
+ "name": "release",
+ "arkOptions": {
+ "obfuscation": {
+ "ruleOptions": {
+ "enable": false,
+ "files": [
+ "./obfuscation-rules.txt"
+ ]
+ }
+ }
+ },
+ "nativeLib": {
+ "debugSymbol": {
+ "strip": true,
+ "exclude": []
+ }
+ }
+ },
+ ],
+ "targets": [
+ {
+ "name": "default"
+ },
+ {
+ "name": "ohosTest",
+ }
+ ]
+}
\ No newline at end of file
diff --git a/code/UI/NdkBuildOnMultiThread/entry/hvigorfile.ts b/code/UI/NdkBuildOnMultiThread/entry/hvigorfile.ts
new file mode 100644
index 0000000000000000000000000000000000000000..cfa8a00f74f409d9647f55cdf270ab6aec69fe41
--- /dev/null
+++ b/code/UI/NdkBuildOnMultiThread/entry/hvigorfile.ts
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { hapTasks } from '@ohos/hvigor-ohos-plugin';
+
+export default {
+ system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
+ plugins: [] /* Custom plugin to extend the functionality of Hvigor. */
+}
\ No newline at end of file
diff --git a/code/UI/NdkBuildOnMultiThread/entry/obfuscation-rules.txt b/code/UI/NdkBuildOnMultiThread/entry/obfuscation-rules.txt
new file mode 100644
index 0000000000000000000000000000000000000000..272efb6ca3f240859091bbbfc7c5802d52793b0b
--- /dev/null
+++ b/code/UI/NdkBuildOnMultiThread/entry/obfuscation-rules.txt
@@ -0,0 +1,23 @@
+# Define project specific obfuscation rules here.
+# You can include the obfuscation configuration files in the current module's build-profile.json5.
+#
+# For more details, see
+# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5
+
+# Obfuscation options:
+# -disable-obfuscation: disable all obfuscations
+# -enable-property-obfuscation: obfuscate the property names
+# -enable-toplevel-obfuscation: obfuscate the names in the global scope
+# -compact: remove unnecessary blank spaces and all line feeds
+# -remove-log: remove all console.* statements
+# -print-namecache: print the name cache that contains the mapping from the old names to new names
+# -apply-namecache: reuse the given cache file
+
+# Keep options:
+# -keep-property-name: specifies property names that you want to keep
+# -keep-global-name: specifies names that you want to keep in the global scope
+
+-enable-property-obfuscation
+-enable-toplevel-obfuscation
+-enable-filename-obfuscation
+-enable-export-obfuscation
\ No newline at end of file
diff --git a/code/UI/NdkBuildOnMultiThread/entry/oh-package-lock.json5 b/code/UI/NdkBuildOnMultiThread/entry/oh-package-lock.json5
new file mode 100644
index 0000000000000000000000000000000000000000..ccf050a5468eb3abf8708258709d87eeecad2ad9
--- /dev/null
+++ b/code/UI/NdkBuildOnMultiThread/entry/oh-package-lock.json5
@@ -0,0 +1,18 @@
+{
+ "meta": {
+ "stableOrder": true
+ },
+ "lockfileVersion": 3,
+ "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.",
+ "specifiers": {
+ "libentry.so@src/main/cpp/types/libentry": "libentry.so@src/main/cpp/types/libentry"
+ },
+ "packages": {
+ "libentry.so@src/main/cpp/types/libentry": {
+ "name": "libentry.so",
+ "version": "1.0.0",
+ "resolved": "src/main/cpp/types/libentry",
+ "registryType": "local"
+ }
+ }
+}
\ No newline at end of file
diff --git a/code/UI/NdkBuildOnMultiThread/entry/oh-package.json5 b/code/UI/NdkBuildOnMultiThread/entry/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..5d993e5251fd56950970aa593aefef1b8d71e976
--- /dev/null
+++ b/code/UI/NdkBuildOnMultiThread/entry/oh-package.json5
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+{
+ "name": "entry",
+ "version": "1.0.0",
+ "description": "Please describe the basic information.",
+ "main": "",
+ "author": "",
+ "license": "",
+ "dependencies": {
+ "libentry.so": "file:./src/main/cpp/types/libentry"
+ }
+}
\ No newline at end of file
diff --git a/code/UI/NdkBuildOnMultiThread/entry/src/main/cpp/CMakeLists.txt b/code/UI/NdkBuildOnMultiThread/entry/src/main/cpp/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..cbb2513ae1e999d51c03f207a4a630430db0c214
--- /dev/null
+++ b/code/UI/NdkBuildOnMultiThread/entry/src/main/cpp/CMakeLists.txt
@@ -0,0 +1,19 @@
+# the minimum version of CMake.
+cmake_minimum_required(VERSION 3.5.0)
+project(myapp)
+
+set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})
+
+if(DEFINED PACKAGE_FIND_FILE)
+ include(${PACKAGE_FIND_FILE})
+endif()
+
+include_directories(${NATIVERENDER_ROOT_PATH}
+ ${NATIVERENDER_ROOT_PATH}/include)
+
+add_library(entry SHARED
+ napi_init.cpp
+ node/NodeCreator.cpp
+ card/CardCreator.cpp
+ )
+target_link_libraries(entry PUBLIC libace_napi.z.so ace_ndk.z.so hilog_ndk.z.so)
\ No newline at end of file
diff --git a/code/UI/NdkBuildOnMultiThread/entry/src/main/cpp/card/CardCreator.cpp b/code/UI/NdkBuildOnMultiThread/entry/src/main/cpp/card/CardCreator.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..44a24ab9e54b9f8fdd5fbeaa43b2eb2a1516c683
--- /dev/null
+++ b/code/UI/NdkBuildOnMultiThread/entry/src/main/cpp/card/CardCreator.cpp
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "CardCreator.h"
+#include "node/TypedArkUINode.h"
+
+namespace NativeModule {
+std::shared_ptr CreateServiceItem(ServiceItemInfo& info)
+{
+ auto stackNode = std::make_shared();
+ stackNode->SetPercentHeight(0.8);
+ stackNode->SetPercentWidth(0.3);
+ stackNode->SetBackgroundColor(0xffeeeeee);
+ stackNode->SetClip(true);
+ stackNode->SetMargin(0, 8, 8, 0);
+ stackNode->SetAlignment(ARKUI_ALIGNMENT_BOTTOM);
+ stackNode->SetBorderRadius(10);
+
+ auto imageNode = std::make_shared();
+ imageNode->SetPercentHeight(1);
+ imageNode->SetPercentWidth(1);
+ imageNode->SetSrc(info.backgroundImageSrc.c_str());
+ imageNode->SetBackgroundColor(0xffff0000);
+ imageNode->SetBorderRadius(10);
+ stackNode->AddChild(imageNode);
+
+ auto colorNode = std::make_shared();
+ colorNode->SetPercentHeight(1);
+ colorNode->SetPercentWidth(1);
+ colorNode->SetBackgroundColor(info.iconColor);;
+ colorNode->SetBorderRadius(10);
+ stackNode->AddChild(colorNode);
+
+ auto columnNode = std::make_shared();
+ columnNode->SetPercentHeight(0.4);
+ columnNode->SetPercentWidth(1);
+ columnNode->SetBackgroundColor(0xffeeeeee);
+ stackNode->AddChild(columnNode);
+
+ auto textNode = std::make_shared();
+ textNode->SetHeight(20);
+ textNode->SetWidth(100);
+ textNode->SetContent(info.DescribeInfo.c_str());
+ textNode->SetFontSize(11);
+ columnNode->AddChild(textNode);
+
+ auto rowNode = std::make_shared();
+ rowNode->SetHeight(20);
+ rowNode->SetWidth(60);
+ rowNode->SetPosition(20, 20);
+ columnNode->AddChild(rowNode);
+
+ auto stackNode2 = std::make_shared();
+ stackNode2->SetPercentHeight(0.8);
+ stackNode2->SetPercentWidth(0.3);
+ stackNode2->SetBackgroundColor(0xffeeeeee);
+ stackNode2->SetClip(true);
+ stackNode2->SetBorderRadius(5);
+ rowNode->AddChild(stackNode2);
+
+ auto image2Node = std::make_shared();
+ image2Node->SetPercentHeight(1);
+ image2Node->SetPercentWidth(1);
+ image2Node->SetSrc(info.iconSrc.c_str());
+ stackNode2->AddChild(image2Node);
+
+ auto colorNode2 = std::make_shared();
+ colorNode2->SetPercentHeight(1);
+ colorNode2->SetPercentWidth(1);
+ colorNode2->SetBackgroundColor(info.iconColor);;
+ stackNode2->AddChild(colorNode2);
+
+ auto text2Node = std::make_shared();
+ text2Node->SetHeight(20);
+ text2Node->SetWidth(70);
+ text2Node->SetFontSize(10);
+ text2Node->SetContent(info.name.c_str());
+ rowNode->AddChild(text2Node);
+
+ return stackNode;
+}
+
+std::shared_ptr CreateAppItem(AppItemInfo& info)
+{
+ auto appItemColumnNode = std::make_shared();
+ appItemColumnNode->SetPercentHeight(1);
+ appItemColumnNode->SetPercentWidth(1);
+ appItemColumnNode->SetPadding(5,5,5,5);
+ appItemColumnNode->SetBackgroundColor(0xffffffff);
+
+ auto stackNode = std::make_shared();
+ stackNode->SetPercentHeight(0.8);
+ stackNode->SetPercentWidth(0.7);
+ stackNode->SetBackgroundColor(0xffeeeeee);
+ stackNode->SetClip(true);
+ stackNode->SetBorderRadius(10);
+ appItemColumnNode->AddChild(stackNode);
+
+ auto appIconNode = std::make_shared();
+ appIconNode->SetPercentHeight(1);
+ appIconNode->SetPercentWidth(1);
+ appIconNode->SetSrc(info.iconSrc.c_str());
+ appIconNode->SetAutoResize(true);
+ appIconNode->SetBorderRadius(5);
+ stackNode->AddChild(appIconNode);
+
+ auto colorNode = std::make_shared();
+ colorNode->SetPercentHeight(1);
+ colorNode->SetPercentWidth(1);
+ colorNode->SetBackgroundColor(info.iconColor);;
+ colorNode->SetBorderRadius(10);
+ stackNode->AddChild(colorNode);
+
+ auto appNameNode = std::make_shared();
+ appNameNode->SetPercentHeight(0.2);
+ appNameNode->SetPercentWidth(0.8);
+ appNameNode->SetFontSize(10);
+ appNameNode->SetContent(info.name.c_str());
+ appItemColumnNode->AddChild(appNameNode);
+
+ return appItemColumnNode;
+}
+
+std::shared_ptr CreateAppCard(AppCardInfo& info)
+{
+ auto columnNode = std::make_shared();
+ columnNode->SetPercentHeight(0.4);
+ columnNode->SetPercentWidth(0.95);
+ columnNode->SetBackgroundColor(0xffffffff);
+ columnNode->SetBorderRadius(10);
+ columnNode->SetPadding(5,5,5,5);
+
+ auto titleTextNode = std::make_shared();
+ titleTextNode->SetPercentWidth(0.9);
+ titleTextNode->SetPercentHeight(0.1);
+ titleTextNode->SetFontSize(16);
+ titleTextNode->SetContent(info.name.c_str());
+ columnNode->AddChild(titleTextNode);
+
+ auto homeGridNode = std::make_shared();
+ homeGridNode->SetPercentHeight(0.9);
+ homeGridNode->SetPercentWidth(1);
+ homeGridNode->SetColumnTemplate("1fr 1fr 1fr 1fr 1fr");
+ homeGridNode->SetColumnGap(3.0);
+ homeGridNode->SetRowGap(0);
+ columnNode->AddChild(homeGridNode);
+
+ for (int32_t i = 0; i < info.items.size(); i++) {
+ auto appItemNode = std::make_shared();
+ appItemNode->SetPercentHeight(0.24);
+ appItemNode->SetPercentWidth(0.2);
+ homeGridNode->AddChild(appItemNode);
+ appItemNode->AddChild(CreateAppItem(info.items[i]));
+ }
+
+ return columnNode;
+}
+
+std::shared_ptr CreateServiceCard(ServiceCardInfo& info)
+{
+ auto columnNode = std::make_shared();
+ columnNode->SetPercentHeight(0.2);
+ columnNode->SetPercentWidth(0.95);
+ columnNode->SetBackgroundColor(0xffffffff);
+ columnNode->SetBorderRadius(10);
+ columnNode->SetPadding(5,5,5,5);
+
+ auto titleTextNode = std::make_shared();
+ titleTextNode->SetPercentWidth(0.9);
+ titleTextNode->SetPercentHeight(0.1);
+ titleTextNode->SetFontSize(16);
+ titleTextNode->SetContent(info.name.c_str());
+ columnNode->AddChild(titleTextNode);
+
+ auto scrollNode = std::make_shared();
+ scrollNode->SetPercentWidth(1);
+ scrollNode->SetPercentHeight(0.9);
+ scrollNode->SetScrollDirection(ARKUI_AXIS_HORIZONTAL);
+ scrollNode->SetScrollBarDisplayMode(ARKUI_SCROLL_BAR_DISPLAY_MODE_OFF);
+ columnNode->AddChild(scrollNode);
+
+ auto rowNode = std::make_shared();
+ scrollNode->AddChild(rowNode);
+
+ for (int32_t i = 0; i < info.items.size(); i++) {
+ rowNode->AddChild(CreateServiceItem(info.items[i]));
+ }
+ return columnNode;
+}
+} // namespace NativeModule
\ No newline at end of file
diff --git a/code/UI/NdkBuildOnMultiThread/entry/src/main/cpp/card/CardCreator.h b/code/UI/NdkBuildOnMultiThread/entry/src/main/cpp/card/CardCreator.h
new file mode 100644
index 0000000000000000000000000000000000000000..1783462a5cbda50f4ce52f01fc3807f1d3e3e677
--- /dev/null
+++ b/code/UI/NdkBuildOnMultiThread/entry/src/main/cpp/card/CardCreator.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MYAPPLICATION_SERVICECARD_H
+#define MYAPPLICATION_SERVICECARD_H
+
+#include "common/ArkUINode.h"
+#include
+
+namespace NativeModule {
+struct ServiceItemInfo {
+ std::string name;
+ std::string backgroundImageSrc;
+ std::string DescribeInfo;
+ std::string iconSrc;
+ int64_t iconColor;
+};
+
+struct AppItemInfo {
+ std::string name;
+ std::string iconSrc;
+ int64_t iconColor;
+};
+
+struct AppCardInfo {
+ std::string name;
+ std::vector items;
+};
+
+struct ServiceCardInfo {
+ std::string name;
+ std::vector items;
+};
+
+struct CardInfo {
+ std::string type;
+ ServiceCardInfo serviceCardInfo;
+ AppCardInfo appCardInfo;
+};
+
+std::shared_ptr CreateServiceCard(ServiceCardInfo& info);
+std::shared_ptr CreateAppCard(AppCardInfo& info);
+} // namespace NativeModule
+
+#endif //MYAPPLICATION_SERVICECARD_H
diff --git a/code/UI/NdkBuildOnMultiThread/entry/src/main/cpp/common/ArkUIBaseNode.h b/code/UI/NdkBuildOnMultiThread/entry/src/main/cpp/common/ArkUIBaseNode.h
new file mode 100644
index 0000000000000000000000000000000000000000..6b4062f608533e3b753cf76bee21bdf2778d2780
--- /dev/null
+++ b/code/UI/NdkBuildOnMultiThread/entry/src/main/cpp/common/ArkUIBaseNode.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MYAPPLICATION_ARKUIBASENODE_H
+#define MYAPPLICATION_ARKUIBASENODE_H
+
+#include
+#include
+#include
+
+#include "NativeModule.h"
+
+namespace NativeModule {
+
+class ArkUIBaseNode {
+public:
+ explicit ArkUIBaseNode(ArkUI_NodeHandle handle)
+ : handle_(handle), nativeModule_(NativeModuleInstance::GetInstance()->GetNativeNodeAPI()) {}
+
+ virtual ~ArkUIBaseNode() {
+ // 封装析构函数,实现子节点移除功能。
+ if (!children_.empty()) {
+ for (const auto& child : children_) {
+ nativeModule_->removeChild(handle_, child->GetHandle());
+ }
+ children_.clear();
+ }
+ // 封装析构函数,统一回收节点资源。
+ nativeModule_->disposeNode(handle_);
+ }
+
+ void AddChild(const std::shared_ptr &child) {
+ children_.emplace_back(child);
+ OnAddChild(child);
+ }
+
+ void RemoveChild(const std::shared_ptr &child) {
+ children_.remove(child);
+ OnRemoveChild(child);
+ }
+
+ void InsertChild(const std::shared_ptr &child, int32_t index) {
+ if (index >= children_.size()) {
+ AddChild(child);
+ } else {
+ auto iter = children_.begin();
+ std::advance(iter, index);
+ children_.insert(iter, child);
+ OnInsertChild(child, index);
+ }
+ }
+
+ ArkUI_NodeHandle GetHandle() const { return handle_; }
+
+protected:
+ // 针对父容器子类需要重载下面的函数,实现组件挂载和卸载。
+ virtual void OnAddChild(const std::shared_ptr &child) = 0;
+ virtual void OnRemoveChild(const std::shared_ptr &child) = 0;
+ virtual void OnInsertChild(const std::shared_ptr &child, int32_t index) = 0;
+
+ ArkUI_NativeNodeAPI_1 *nativeModule_ = nullptr;
+ ArkUI_NodeHandle handle_;
+private:
+ std::list> children_;
+};
+} // namespace NativeModule
+
+#endif // MYAPPLICATION_ARKUIBASENODE_H
\ No newline at end of file
diff --git a/code/UI/NdkBuildOnMultiThread/entry/src/main/cpp/common/ArkUINode.h b/code/UI/NdkBuildOnMultiThread/entry/src/main/cpp/common/ArkUINode.h
new file mode 100644
index 0000000000000000000000000000000000000000..e2aa016e781bfdb3555a90b725dbdac348bf194d
--- /dev/null
+++ b/code/UI/NdkBuildOnMultiThread/entry/src/main/cpp/common/ArkUINode.h
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MYAPPLICATION_ARKUINODE_H
+#define MYAPPLICATION_ARKUINODE_H
+
+#include "ArkUIBaseNode.h"
+
+namespace NativeModule {
+
+class ArkUINode : public ArkUIBaseNode {
+public:
+ explicit ArkUINode(ArkUI_NodeHandle handle) : ArkUIBaseNode(handle) {}
+
+ ~ArkUINode() override {}
+
+ // NDK相关通用属性调用封装
+ void SetWidth(float width) {
+ assert(handle_);
+ ArkUI_NumberValue value[] = {{.f32 = width}};
+ ArkUI_AttributeItem item = {value, 1};
+ auto result = nativeModule_->setAttribute(handle_, NODE_WIDTH, &item);
+ if (result != ARKUI_ERROR_CODE_NO_ERROR) {
+ OH_LOG_ERROR(LOG_APP, "ArkUINode SetWidth Failed %{public}d", result);
+ }
+ }
+ void SetPercentWidth(float percent) {
+ assert(handle_);
+ ArkUI_NumberValue value[] = {{.f32 = percent}};
+ ArkUI_AttributeItem item = {value, 1};
+ auto result = nativeModule_->setAttribute(handle_, NODE_WIDTH_PERCENT, &item);
+ if (result != ARKUI_ERROR_CODE_NO_ERROR) {
+ OH_LOG_ERROR(LOG_APP, "ArkUINode SetPercentWidth Failed %{public}d", result);
+ }
+ }
+ void SetHeight(float height) {
+ assert(handle_);
+ ArkUI_NumberValue value[] = {{.f32 = height}};
+ ArkUI_AttributeItem item = {value, 1};
+ auto result = nativeModule_->setAttribute(handle_, NODE_HEIGHT, &item);
+ if (result != ARKUI_ERROR_CODE_NO_ERROR) {
+ OH_LOG_ERROR(LOG_APP, "ArkUINode SetHeight Failed %{public}d", result);
+ }
+ }
+ void SetPercentHeight(float percent) {
+ assert(handle_);
+ ArkUI_NumberValue value[] = {{.f32 = percent}};
+ ArkUI_AttributeItem item = {value, 1};
+ auto result = nativeModule_->setAttribute(handle_, NODE_HEIGHT_PERCENT, &item);
+ if (result != ARKUI_ERROR_CODE_NO_ERROR) {
+ OH_LOG_ERROR(LOG_APP, "ArkUINode SetPercentHeight Failed %{public}d", result);
+ }
+ }
+ void SetPosition(float x, float y) {
+ assert(handle_);
+ ArkUI_NumberValue value[] = {{.f32 = x}, {.f32 = y}};
+ ArkUI_AttributeItem item = {value, 2};
+ auto result = nativeModule_->setAttribute(handle_, NODE_POSITION, &item);
+ if (result != ARKUI_ERROR_CODE_NO_ERROR) {
+ OH_LOG_ERROR(LOG_APP, "ArkUINode SetPosition Failed %{public}d", result);
+ }
+ }
+ void SetBackgroundColor(uint32_t color) {
+ assert(handle_);
+ ArkUI_NumberValue value[] = {{.u32 = color}};
+ ArkUI_AttributeItem item = {value, 1};
+ auto result = nativeModule_->setAttribute(handle_, NODE_BACKGROUND_COLOR, &item);
+ if (result != ARKUI_ERROR_CODE_NO_ERROR) {
+ OH_LOG_ERROR(LOG_APP, "ArkUINode SetBackgroundColor Failed %{public}d", result);
+ }
+ }
+ void SetForegroundColor(uint32_t color) {
+ assert(handle_);
+ ArkUI_NumberValue value[] = {{.u32 = color}};
+ ArkUI_AttributeItem item = {value, 1};
+ auto result = nativeModule_->setAttribute(handle_, NODE_FOREGROUND_COLOR, &item);
+ if (result != ARKUI_ERROR_CODE_NO_ERROR) {
+ OH_LOG_ERROR(LOG_APP, "ArkUINode SetForegroundColor Failed %{public}d", result);
+ }
+ }
+
+ void SetBorderRadius(float borderRadius) {
+ assert(handle_);
+ ArkUI_NumberValue value[] = {{.f32 = borderRadius}};
+ ArkUI_AttributeItem item = {value, 1};
+ auto result = nativeModule_->setAttribute(handle_, NODE_BORDER_RADIUS, &item);
+ if (result != ARKUI_ERROR_CODE_NO_ERROR) {
+ OH_LOG_ERROR(LOG_APP, "ArkUINode SetBorderRadius Failed %{public}d", result);
+ }
+ }
+ void SetMargin(float top, float right, float bottom, float left) {
+ assert(handle_);
+ ArkUI_NumberValue value[] = {{.f32 = top}, {.f32 = right}, {.f32 = bottom}, {.f32 = left}};
+ ArkUI_AttributeItem item = {value, 4};
+ auto result = nativeModule_->setAttribute(handle_, NODE_MARGIN, &item);
+ if (result != ARKUI_ERROR_CODE_NO_ERROR) {
+ OH_LOG_ERROR(LOG_APP, "ArkUINode SetMargin Failed %{public}d", result);
+ }
+ }
+ void SetPadding(float top, float right, float bottom, float left) {
+ assert(handle_);
+ ArkUI_NumberValue value[] = {{.f32 = top}, {.f32 = right}, {.f32 = bottom}, {.f32 = left}};
+ ArkUI_AttributeItem item = {value, 4};
+ auto result = nativeModule_->setAttribute(handle_, NODE_PADDING, &item);
+ if (result != ARKUI_ERROR_CODE_NO_ERROR) {
+ OH_LOG_ERROR(LOG_APP, "ArkUINode SetPadding Failed %{public}d", result);
+ }
+ }
+ void SetClip(bool clip) {
+ assert(handle_);
+ ArkUI_NumberValue value[] = {{.i32 = clip}};
+ ArkUI_AttributeItem item = {value, 1};
+ auto result = nativeModule_->setAttribute(handle_, NODE_CLIP, &item);
+ if (result != ARKUI_ERROR_CODE_NO_ERROR) {
+ OH_LOG_ERROR(LOG_APP, "ArkUINode SetClip Failed %{public}d", result);
+ }
+ }
+
+ void SetAlignment(ArkUI_Alignment alignment) {
+ assert(handle_);
+ ArkUI_NumberValue value[] = {{.i32 = alignment}};
+ ArkUI_AttributeItem item = {value, 1};
+ auto result = nativeModule_->setAttribute(handle_, NODE_ALIGNMENT, &item);
+ if (result != ARKUI_ERROR_CODE_NO_ERROR) {
+ OH_LOG_ERROR(LOG_APP, "ArkUINode SetAlignment Failed %{public}d", result);
+ }
+ }
+
+protected:
+ // 组件树操作的实现类对接。
+ void OnAddChild(const std::shared_ptr &child) override {
+ auto result = nativeModule_->addChild(handle_, child->GetHandle());
+ if (result != ARKUI_ERROR_CODE_NO_ERROR) {
+ OH_LOG_ERROR(LOG_APP, "ArkUINode AddChild Failed %{public}d", result);
+ }
+ }
+ void OnRemoveChild(const std::shared_ptr &child) override {
+ auto result = nativeModule_->removeChild(handle_, child->GetHandle());
+ if (result != ARKUI_ERROR_CODE_NO_ERROR) {
+ OH_LOG_ERROR(LOG_APP, "ArkUINode RemoveChild Failed %{public}d", result);
+ }
+ }
+ void OnInsertChild(const std::shared_ptr &child, int32_t index) override {
+ auto result = nativeModule_->insertChildAt(handle_, child->GetHandle(), index);
+ if (result != ARKUI_ERROR_CODE_NO_ERROR) {
+ OH_LOG_ERROR(LOG_APP, "ArkUINode InsertChild Failed %{public}d", result);
+ }
+ }
+};
+} // namespace NativeModule
+
+#endif // MYAPPLICATION_ARKUINODE_H
diff --git a/code/UI/NdkBuildOnMultiThread/entry/src/main/cpp/common/NativeModule.h b/code/UI/NdkBuildOnMultiThread/entry/src/main/cpp/common/NativeModule.h
new file mode 100644
index 0000000000000000000000000000000000000000..e73064d707f7475d2081abefb8556a2ff7ee1afa
--- /dev/null
+++ b/code/UI/NdkBuildOnMultiThread/entry/src/main/cpp/common/NativeModule.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#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
diff --git a/code/UI/NdkBuildOnMultiThread/entry/src/main/cpp/data/MockData.h b/code/UI/NdkBuildOnMultiThread/entry/src/main/cpp/data/MockData.h
new file mode 100644
index 0000000000000000000000000000000000000000..4fadc4c2c5c67b0b51045ef586cb910ba9ae304d
--- /dev/null
+++ b/code/UI/NdkBuildOnMultiThread/entry/src/main/cpp/data/MockData.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MYAPPLICATION_MOCKDATA_H
+#define MYAPPLICATION_MOCKDATA_H
+#include "card/CardCreator.h"
+
+namespace NativeModule {
+
+#define CARD_RED 0xffc94b51
+#define CARD_BLUE 0xff5b97c7
+#define CARD_GREEN 0xff70c06f
+#define CARD_YELLOW 0xffcbbb4d
+#define CARD_PURPLE 0xffab70b1
+
+std::vector g_appItems = {
+ {"测试文本", "resource://media/startIcon.png", CARD_YELLOW},
+ {"测试文本", "resource://media/startIcon.png", CARD_RED},
+ {"测试文本", "resource://media/startIcon.png", CARD_PURPLE},
+ {"测试文本", "resource://media/startIcon.png", CARD_BLUE},
+ {"测试文本", "resource://media/startIcon.png", CARD_GREEN},
+ {"测试文本", "resource://media/startIcon.png", CARD_RED},
+ {"测试文本", "resource://media/startIcon.png", CARD_BLUE},
+ {"测试文本", "resource://media/startIcon.png", CARD_PURPLE},
+ {"测试文本", "resource://media/startIcon.png", CARD_BLUE},
+ {"测试文本", "resource://media/startIcon.png", CARD_RED},
+ {"测试文本", "resource://media/startIcon.png", CARD_BLUE},
+ {"测试文本", "resource://media/startIcon.png", CARD_GREEN},
+ {"测试文本", "resource://media/startIcon.png", CARD_YELLOW},
+ {"测试文本", "resource://media/startIcon.png", CARD_RED},
+ {"测试文本", "resource://media/startIcon.png", CARD_BLUE},
+ {"测试文本", "resource://media/startIcon.png", CARD_YELLOW},
+ {"测试文本", "resource://media/startIcon.png", CARD_PURPLE},
+ {"测试文本", "resource://media/startIcon.png", CARD_GREEN},
+ {"测试文本", "resource://media/startIcon.png", CARD_RED},
+};
+
+std::vector g_serviceItems = {
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_YELLOW},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_RED},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_PURPLE},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_BLUE},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_GREEN},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_BLUE},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_YELLOW},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_BLUE},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_RED},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_YELLOW},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_GREEN},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_BLUE},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本 ", "resource://media/startIcon.png", CARD_YELLOW},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_BLUE},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_RED},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_PURPLE},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_YELLOW},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_GREEN},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_YELLOW},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_RED},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_PURPLE},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_BLUE},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_GREEN},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_BLUE},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_YELLOW},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_BLUE},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_RED},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_YELLOW},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_GREEN},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_BLUE},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_YELLOW},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_BLUE},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_RED},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_PURPLE},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_YELLOW},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_GREEN},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_YELLOW},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_RED},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_PURPLE},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_BLUE},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_GREEN},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_BLUE},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_YELLOW},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_BLUE},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_RED},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_YELLOW},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_GREEN},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_BLUE},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_YELLOW},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_BLUE},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_RED},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_PURPLE},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_YELLOW},
+ {"测试文本", "resource://media/startIcon.png", "测试文本 测试文本", "resource://media/startIcon.png", CARD_GREEN},
+};
+
+std::vector g_cardTypeInfos = {
+ {"App" , {} , { "测试文本1", g_appItems }},
+ {"Service" , { "测试文本2", g_serviceItems }, {}},
+ {"App" , {} , { "测试文本3", g_appItems }},
+ {"App" , {} , { "测试文本4", g_appItems }},
+ {"Service" , { "测试文本5", g_serviceItems }, {}},
+ {"App" , {} , { "测试文本6", g_appItems }},
+};
+}
+#endif //MYAPPLICATION_MOCKDATA_H
diff --git a/code/UI/NdkBuildOnMultiThread/entry/src/main/cpp/napi_init.cpp b/code/UI/NdkBuildOnMultiThread/entry/src/main/cpp/napi_init.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c2e6430d4830979cdf4eaaa304da453eaff54d62
--- /dev/null
+++ b/code/UI/NdkBuildOnMultiThread/entry/src/main/cpp/napi_init.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "napi/native_api.h"
+#include "node/NodeCreator.h"
+
+EXTERN_C_START
+static napi_value Init(napi_env env, napi_value exports)
+{
+ napi_property_descriptor desc[] = {
+ { "CreateNodeTreeOnUIThread", nullptr, NativeModule::CreateNodeTreeOnUIThread, nullptr, nullptr, nullptr, napi_default, nullptr },
+ { "CreateNodeTreeOnMultiThread", nullptr, NativeModule::CreateNodeTreeOnMultiThread, nullptr, nullptr, nullptr, napi_default, nullptr },
+ { "DisposeNodeTree", nullptr, NativeModule::DisposeNodeTree, nullptr, nullptr, nullptr, napi_default, nullptr }
+ };
+ napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
+ return exports;
+}
+EXTERN_C_END
+
+static napi_module entryModule = {
+ .nm_version = 1,
+ .nm_flags = 0,
+ .nm_filename = nullptr,
+ .nm_register_func = Init,
+ .nm_modname = "entry",
+ .nm_priv = ((void*)0),
+ .reserved = { 0 },
+};
+
+extern "C" __attribute__((constructor)) void RegisterEntryModule(void)
+{
+ napi_module_register(&entryModule);
+}
diff --git a/code/UI/NdkBuildOnMultiThread/entry/src/main/cpp/node/NodeCreator.cpp b/code/UI/NdkBuildOnMultiThread/entry/src/main/cpp/node/NodeCreator.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..03f1f98385f2ba4794e63359e8fa466e9f5e7138
--- /dev/null
+++ b/code/UI/NdkBuildOnMultiThread/entry/src/main/cpp/node/NodeCreator.cpp
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2025 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "node/NodeCreator.h"
+
+#include
+#include