1e41f4b71Sopenharmony_ci# Mutual Invoking Between the Application Side and Frontend Pages (C/C++)
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ciThis guide applies to the communication between the ArkWeb application side and frontend pages. You can use the ArkWeb native APIs to complete the service communication mechanism (JSBridge for short) based on the application architecture.
4e41f4b71Sopenharmony_ci
5e41f4b71Sopenharmony_ci## Applicable Application Architecture
6e41f4b71Sopenharmony_ci
7e41f4b71Sopenharmony_ciIf an application is developed using ArkTS and C++ language, or if its architecture is close to that of a mini-program, with a built-in C++ environment, you are advised to use the [ArkWeb_ControllerAPI](../reference/apis-arkweb/_ark_web___controller_a_p_i.md#arkweb_controllerapi) and [ArkWeb_ComponentAPI](../reference/apis-arkweb/_ark_web___component_a_p_i.md#arkweb_componentapi) provided by ArkWeb on the native side to implement the JSBridge functionality.
8e41f4b71Sopenharmony_ci
9e41f4b71Sopenharmony_ci  ![arkweb_jsbridge_arch](figures/arkweb_jsbridge_arch.png)
10e41f4b71Sopenharmony_ci
11e41f4b71Sopenharmony_ci  The preceding figure shows a general architecture of mini-programs with universal applicability. When the logic layer is run using the built-in JavaScript of the application, the native API can be used to communicate with the view layer (ArkWeb as the renderer) in the C++ environment. You do not need to call JSBridge-related APIs in the ArkTS environment.
12e41f4b71Sopenharmony_ci
13e41f4b71Sopenharmony_ci  ![arkweb_jsbridge_diff](figures/arkweb_jsbridge_diff.png)
14e41f4b71Sopenharmony_ci
15e41f4b71Sopenharmony_ci  The native JSBridge APIs are provided to avoid unnecessary switching to the ArkTS environment and allow callback to be reported in non-UI threads to avoid UI blocking.
16e41f4b71Sopenharmony_ci
17e41f4b71Sopenharmony_ci## Using Native APIs for JSBridge Communication
18e41f4b71Sopenharmony_ci
19e41f4b71Sopenharmony_ci### ArkWeb Binding on the Native Side
20e41f4b71Sopenharmony_ci
21e41f4b71Sopenharmony_ci* The **ArkWeb** component is declared on the ArkTS side. You need to define a **webTag** and transfer the **webTag** to the application C++ side using the NAPI. The **webTag** is used as the unique identifier of the corresponding component when an ArkWeb native API is used.
22e41f4b71Sopenharmony_ci
23e41f4b71Sopenharmony_ci* ArkTS side:
24e41f4b71Sopenharmony_ci
25e41f4b71Sopenharmony_ci  ```js
26e41f4b71Sopenharmony_ci  // Define a webTag and transfer it as an input parameter when WebviewController is created to establish the mapping between controller and webTag.
27e41f4b71Sopenharmony_ci  webTag: string = 'ArkWeb1';
28e41f4b71Sopenharmony_ci  controller: web_webview.WebviewController = new web_webview.WebviewController(this.webTag);
29e41f4b71Sopenharmony_ci  ...
30e41f4b71Sopenharmony_ci  // Use aboutToAppear() to transfer the webTag to the C++ side through the NAPI API. The webTag uniquely identifies the ArkWeb component on the C++ side.
31e41f4b71Sopenharmony_ci  aboutToAppear() {
32e41f4b71Sopenharmony_ci    console.info("aboutToAppear")
33e41f4b71Sopenharmony_ci    // Initialize the web NDK.
34e41f4b71Sopenharmony_ci    testNapi.nativeWebInit(this.webTag);
35e41f4b71Sopenharmony_ci  }
36e41f4b71Sopenharmony_ci  ...
37e41f4b71Sopenharmony_ci  ```
38e41f4b71Sopenharmony_ci
39e41f4b71Sopenharmony_ci* C++ side:
40e41f4b71Sopenharmony_ci
41e41f4b71Sopenharmony_ci  ```c++
42e41f4b71Sopenharmony_ci  // Parse and store the webTag.
43e41f4b71Sopenharmony_ci  static napi_value NativeWebInit(napi_env env, napi_callback_info info) {
44e41f4b71Sopenharmony_ci      OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "ndk NativeWebInit start");
45e41f4b71Sopenharmony_ci      size_t argc = 1;
46e41f4b71Sopenharmony_ci      napi_value args[1] = {nullptr};
47e41f4b71Sopenharmony_ci      napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
48e41f4b71Sopenharmony_ci      // Obtain the first parameter webTag.
49e41f4b71Sopenharmony_ci      size_t webTagSize = 0;
50e41f4b71Sopenharmony_ci      napi_get_value_string_utf8(env, args[0], nullptr, 0, &webTagSize);
51e41f4b71Sopenharmony_ci      char *webTagValue = new (std::nothrow) char[webTagSize + 1];
52e41f4b71Sopenharmony_ci      size_t webTagLength = 0;
53e41f4b71Sopenharmony_ci      napi_get_value_string_utf8(env, args[0], webTagValue, webTagSize + 1, &webTagLength);
54e41f4b71Sopenharmony_ci      OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "ArkWeb", "ndk NativeWebInit webTag:%{public}s", webTagValue);
55e41f4b71Sopenharmony_ci
56e41f4b71Sopenharmony_ci      // Save the webTag in the instance object.
57e41f4b71Sopenharmony_ci      jsbridge_object_ptr = std::make_shared<JSBridgeObject>(webTagValue);
58e41f4b71Sopenharmony_ci  ...
59e41f4b71Sopenharmony_ci  ```
60e41f4b71Sopenharmony_ci
61e41f4b71Sopenharmony_ci### Obtaining the API Struct on the Native Side
62e41f4b71Sopenharmony_ci
63e41f4b71Sopenharmony_ciYou can obtain the native API of ArkWeb using the API [OH_ArkWeb_GetNativeAPI](../reference/apis-arkweb/_ark_web___any_native_a_p_i.md#arkweb_anynativeapi), and the function pointer structs [ArkWeb_ControllerAPI](../reference/apis-arkweb/_ark_web___controller_a_p_i.md#arkweb_controllerapi) and [ArkWeb_ComponentAPI](../reference/apis-arkweb/_ark_web___component_a_p_i.md#arkweb_componentapi) can be obtained based on the input parameter type. The [ArkWeb_ControllerAPI](../reference/apis-arkweb/_ark_web___controller_a_p_i.md#arkweb_controllerapi) corresponds to the [web_webview.WebviewController API](../reference/apis-arkweb/js-apis-webview.md) on ArkTS, and the [ArkWeb_ComponentAPI](../reference/apis-arkweb/_ark_web___component_a_p_i.md#arkweb_componentapi) corresponds to the [ArkWeb component API](../reference/apis-arkweb/ts-basic-components-web.md) on ArkTS.
64e41f4b71Sopenharmony_ci
65e41f4b71Sopenharmony_ci  ```c++
66e41f4b71Sopenharmony_ci  static ArkWeb_ControllerAPI *controller = nullptr;
67e41f4b71Sopenharmony_ci  static ArkWeb_ComponentAPI *component = nullptr;
68e41f4b71Sopenharmony_ci  ...
69e41f4b71Sopenharmony_ci  controller = reinterpret_cast<ArkWeb_ControllerAPI *>(OH_ArkWeb_GetNativeAPI(ARKWEB_NATIVE_CONTROLLER));
70e41f4b71Sopenharmony_ci  component = reinterpret_cast<ArkWeb_ComponentAPI *>(OH_ArkWeb_GetNativeAPI(ARKWEB_NATIVE_COMPONENT));
71e41f4b71Sopenharmony_ci  ```
72e41f4b71Sopenharmony_ci
73e41f4b71Sopenharmony_ci### Registering Component Lifecycle Callback on the Native Side
74e41f4b71Sopenharmony_ci
75e41f4b71Sopenharmony_ciUse [ArkWeb Component API](../reference/apis-arkweb/_ark_web___component_a_p_i.md#arkweb_componentapi) to register the component lifecycle callback. To avoid crash caused by mismatch between the SDK and device ROM, you are advised to use [ARKWEB_MEMBER_MISSING](../reference/apis-arkweb/_web.md#arkweb_member_missing) to check whether there is a pointer to the function struct before calling an API.
76e41f4b71Sopenharmony_ci
77e41f4b71Sopenharmony_ci  ```c++
78e41f4b71Sopenharmony_ci  if (!ARKWEB_MEMBER_MISSING(component, onControllerAttached)) {
79e41f4b71Sopenharmony_ci      component->onControllerAttached(webTagValue, ValidCallback,
80e41f4b71Sopenharmony_ci                                      static_cast<void *>(jsbridge_object_ptr->GetWeakPtr()));
81e41f4b71Sopenharmony_ci  } else {
82e41f4b71Sopenharmony_ci      OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "ArkWeb", "component onControllerAttached func not exist");
83e41f4b71Sopenharmony_ci  }
84e41f4b71Sopenharmony_ci
85e41f4b71Sopenharmony_ci  if (!ARKWEB_MEMBER_MISSING(component, onPageBegin)) {
86e41f4b71Sopenharmony_ci      component->onPageBegin(webTagValue, LoadStartCallback,
87e41f4b71Sopenharmony_ci                                      static_cast<void *>(jsbridge_object_ptr->GetWeakPtr()));
88e41f4b71Sopenharmony_ci  } else {
89e41f4b71Sopenharmony_ci      OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "ArkWeb", "component onPageBegin func not exist");
90e41f4b71Sopenharmony_ci  }
91e41f4b71Sopenharmony_ci
92e41f4b71Sopenharmony_ci  if (!ARKWEB_MEMBER_MISSING(component, onPageEnd)) {
93e41f4b71Sopenharmony_ci      component->onPageEnd(webTagValue, LoadEndCallback,
94e41f4b71Sopenharmony_ci                                      static_cast<void *>(jsbridge_object_ptr->GetWeakPtr()));
95e41f4b71Sopenharmony_ci  } else {
96e41f4b71Sopenharmony_ci      OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "ArkWeb", "component onPageEnd func not exist");
97e41f4b71Sopenharmony_ci  }
98e41f4b71Sopenharmony_ci
99e41f4b71Sopenharmony_ci  if (!ARKWEB_MEMBER_MISSING(component, onDestroy)) {
100e41f4b71Sopenharmony_ci      component->onDestroy(webTagValue, DestroyCallback,
101e41f4b71Sopenharmony_ci                                      static_cast<void *>(jsbridge_object_ptr->GetWeakPtr()));
102e41f4b71Sopenharmony_ci  } else {
103e41f4b71Sopenharmony_ci      OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "ArkWeb", "component onDestroy func not exist");
104e41f4b71Sopenharmony_ci  }
105e41f4b71Sopenharmony_ci  ```
106e41f4b71Sopenharmony_ci
107e41f4b71Sopenharmony_ci### Invoking Application Functions on the Frontend Page
108e41f4b71Sopenharmony_ci
109e41f4b71Sopenharmony_ciUse [registerJavaScriptProxy](../reference/apis-arkweb/_ark_web___controller_a_p_i.md#registerjavascriptproxy) to register the application function with the frontend page. You are advised to register the function in callback [onControllerAttached](../reference/apis-arkweb/_ark_web___component_a_p_i.md#oncontrollerattached). In other cases, you need to call [refresh](../reference/apis-arkweb/_ark_web___controller_a_p_i.md#refresh) for the registration.
110e41f4b71Sopenharmony_ci
111e41f4b71Sopenharmony_ci  ```c++
112e41f4b71Sopenharmony_ci  // Register an object.
113e41f4b71Sopenharmony_ci  OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "ndk RegisterJavaScriptProxy begin");
114e41f4b71Sopenharmony_ci  ArkWeb_ProxyMethod method1 = {"method1", ProxyMethod1, static_cast<void *>(jsbridge_object_ptr->GetWeakPt  ())};
115e41f4b71Sopenharmony_ci  ArkWeb_ProxyMethod method2 = {"method2", ProxyMethod2, static_cast<void *>(jsbridge_object_ptr->GetWeakPt  ())};
116e41f4b71Sopenharmony_ci  ArkWeb_ProxyMethod methodList[2] = {method1, method2};
117e41f4b71Sopenharmony_ci  // Invoke the native API to register the object.
118e41f4b71Sopenharmony_ci  // In this case, you can use proxy.method1 and proxy.method2 to call ProxyMethod1 and ProxyMethod2 in this file on the HTML5 side.
119e41f4b71Sopenharmony_ci  ArkWeb_ProxyObject proxyObject = {"ndkProxy", methodList, 2};
120e41f4b71Sopenharmony_ci  controller->registerJavaScriptProxy(webTag, &proxyObject);
121e41f4b71Sopenharmony_ci  ```
122e41f4b71Sopenharmony_ci
123e41f4b71Sopenharmony_ci### Invoking Frontend Page Functions on the Application
124e41f4b71Sopenharmony_ci
125e41f4b71Sopenharmony_ciUse [runJavaScript](../reference/apis-arkweb/_ark_web___controller_a_p_i.md#runjavascript) to invoke frontend page functions.
126e41f4b71Sopenharmony_ci
127e41f4b71Sopenharmony_ci  ```c++
128e41f4b71Sopenharmony_ci  // Construct a struct executed in runJS.
129e41f4b71Sopenharmony_ci  char* jsCode = "runJSRetStr()";
130e41f4b71Sopenharmony_ci  ArkWeb_JavaScriptObject object = {(uint8_t *)jsCode, bufferSize, &JSBridgeObject::StaticRunJavaScriptCallback,
131e41f4b71Sopenharmony_ci                                       static_cast<void *>(jsbridge_object_ptr->GetWeakPtr())};
132e41f4b71Sopenharmony_ci  // Invoke the **runJSRetStr()** function of the frontend page.
133e41f4b71Sopenharmony_ci  controller->runJavaScript(webTagValue, &object);
134e41f4b71Sopenharmony_ci  ```
135e41f4b71Sopenharmony_ci
136e41f4b71Sopenharmony_ci### Sample Code
137e41f4b71Sopenharmony_ci
138e41f4b71Sopenharmony_ci* Frontend page code in **entry/src/main/resources/rawfile/runJS.html**:
139e41f4b71Sopenharmony_ci
140e41f4b71Sopenharmony_ci  ```html
141e41f4b71Sopenharmony_ci  <!DOCTYPE html>
142e41f4b71Sopenharmony_ci  <html lang="en-gb">
143e41f4b71Sopenharmony_ci  <head>
144e41f4b71Sopenharmony_ci      <meta name="viewport" content="width=device-width, initial-scale=1.0">
145e41f4b71Sopenharmony_ci      <title>run javascript demo</title>
146e41f4b71Sopenharmony_ci  </head>
147e41f4b71Sopenharmony_ci  <body>
148e41f4b71Sopenharmony_ci  <h1>run JavaScript Ext demo</h1>
149e41f4b71Sopenharmony_ci  <p id="webDemo"></p>
150e41f4b71Sopenharmony_ci  <br>
151e41f4b71Sopenharmony_ci  <button type="button" style="height:30px;width:200px" onclick="testNdkProxyObjMethod1()">test ndk method1 ! </button>
152e41f4b71Sopenharmony_ci  <br>
153e41f4b71Sopenharmony_ci  <br>
154e41f4b71Sopenharmony_ci  <button type="button" style="height:30px;width:200px" onclick="testNdkProxyObjMethod2()">test ndk method2 ! </button>
155e41f4b71Sopenharmony_ci  <br>
156e41f4b71Sopenharmony_ci
157e41f4b71Sopenharmony_ci  </body>
158e41f4b71Sopenharmony_ci  <script type="text/javascript">
159e41f4b71Sopenharmony_ci
160e41f4b71Sopenharmony_ci  function testNdkProxyObjMethod1() {
161e41f4b71Sopenharmony_ci        if (window.ndkProxy == undefined) {
162e41f4b71Sopenharmony_ci              document.getElementById("webDemo").innerHTML = "ndkProxy undefined"
163e41f4b71Sopenharmony_ci              return "objName undefined"
164e41f4b71Sopenharmony_ci        }
165e41f4b71Sopenharmony_ci
166e41f4b71Sopenharmony_ci        if (window.ndkProxy.method1 == undefined) {
167e41f4b71Sopenharmony_ci              document.getElementById("webDemo").innerHTML = "ndkProxy method1 undefined"
168e41f4b71Sopenharmony_ci              return "objName  test undefined"
169e41f4b71Sopenharmony_ci        }
170e41f4b71Sopenharmony_ci
171e41f4b71Sopenharmony_ci        if (window.ndkProxy.method2 == undefined) {
172e41f4b71Sopenharmony_ci              document.getElementById("webDemo").innerHTML = "ndkProxy method2 undefined"
173e41f4b71Sopenharmony_ci              return "objName  test undefined"
174e41f4b71Sopenharmony_ci        }
175e41f4b71Sopenharmony_ci        var retStr = window.ndkProxy.method1("hello", "world", [1.2, -3.4, 123.456], ["Saab", "Volvo", "BMW", undefined], 1.23456, 123789, true, false, 0,  undefined);
176e41f4b71Sopenharmony_ci        document.getElementById("webDemo").innerHTML  = "ndkProxy and method1 is ok, " + retStr;
177e41f4b71Sopenharmony_ci  }
178e41f4b71Sopenharmony_ci
179e41f4b71Sopenharmony_ci  function testNdkProxyObjMethod2() {
180e41f4b71Sopenharmony_ci        if (window.ndkProxy == undefined) {
181e41f4b71Sopenharmony_ci              document.getElementById("webDemo").innerHTML = "ndkProxy undefined"
182e41f4b71Sopenharmony_ci              return "objName undefined"
183e41f4b71Sopenharmony_ci        }
184e41f4b71Sopenharmony_ci
185e41f4b71Sopenharmony_ci        if (window.ndkProxy.method1 == undefined) {
186e41f4b71Sopenharmony_ci              document.getElementById("webDemo").innerHTML = "ndkProxy method1 undefined"
187e41f4b71Sopenharmony_ci              return "objName  test undefined"
188e41f4b71Sopenharmony_ci        }
189e41f4b71Sopenharmony_ci
190e41f4b71Sopenharmony_ci        if (window.ndkProxy.method2 == undefined) {
191e41f4b71Sopenharmony_ci              document.getElementById("webDemo").innerHTML = "ndkProxy method2 undefined"
192e41f4b71Sopenharmony_ci              return "objName  test undefined"
193e41f4b71Sopenharmony_ci        }
194e41f4b71Sopenharmony_ci
195e41f4b71Sopenharmony_ci      var student = {
196e41f4b71Sopenharmony_ci              name:"zhang",
197e41f4b71Sopenharmony_ci              sex:"man",
198e41f4b71Sopenharmony_ci              age:25
199e41f4b71Sopenharmony_ci      };
200e41f4b71Sopenharmony_ci      var cars = [student, 456, false, 4.567];
201e41f4b71Sopenharmony_ci      let params = "[\"{\\\"scope\\\"]";
202e41f4b71Sopenharmony_ci
203e41f4b71Sopenharmony_ci      var retStr = window.ndkProxy.method2("hello", "world", false, cars, params);
204e41f4b71Sopenharmony_ci      document.getElementById("webDemo").innerHTML  = "ndkProxy and method2 is ok, " + retStr;
205e41f4b71Sopenharmony_ci  }
206e41f4b71Sopenharmony_ci
207e41f4b71Sopenharmony_ci  function runJSRetStr(data) {
208e41f4b71Sopenharmony_ci      const d = new Date();
209e41f4b71Sopenharmony_ci      let time = d.getTime();
210e41f4b71Sopenharmony_ci      return JSON.stringify(time)
211e41f4b71Sopenharmony_ci  }
212e41f4b71Sopenharmony_ci  </script>
213e41f4b71Sopenharmony_ci  </html>
214e41f4b71Sopenharmony_ci  ```
215e41f4b71Sopenharmony_ci
216e41f4b71Sopenharmony_ci* ArkTS code in **entry/src/main/ets/pages/Index.ets**:
217e41f4b71Sopenharmony_ci
218e41f4b71Sopenharmony_ci  ```javascript
219e41f4b71Sopenharmony_ci  import testNapi from 'libentry.so';
220e41f4b71Sopenharmony_ci  import { webview } from '@kit.ArkWeb';
221e41f4b71Sopenharmony_ci
222e41f4b71Sopenharmony_ci  class testObj {
223e41f4b71Sopenharmony_ci    constructor() {
224e41f4b71Sopenharmony_ci    }
225e41f4b71Sopenharmony_ci
226e41f4b71Sopenharmony_ci    test(): string {
227e41f4b71Sopenharmony_ci      console.log('ArkUI Web Component');
228e41f4b71Sopenharmony_ci      return "ArkUI Web Component";
229e41f4b71Sopenharmony_ci    }
230e41f4b71Sopenharmony_ci
231e41f4b71Sopenharmony_ci    toString(): void {
232e41f4b71Sopenharmony_ci      console.log('Web Component toString');
233e41f4b71Sopenharmony_ci    }
234e41f4b71Sopenharmony_ci  }
235e41f4b71Sopenharmony_ci
236e41f4b71Sopenharmony_ci  @Entry
237e41f4b71Sopenharmony_ci  @Component
238e41f4b71Sopenharmony_ci  struct Index {
239e41f4b71Sopenharmony_ci    webTag: string = 'ArkWeb1';
240e41f4b71Sopenharmony_ci    controller: webview.WebviewController = new webview.WebviewController(this.webTag);
241e41f4b71Sopenharmony_ci    @State testObjtest: testObj = new testObj();
242e41f4b71Sopenharmony_ci
243e41f4b71Sopenharmony_ci    aboutToAppear() {
244e41f4b71Sopenharmony_ci      console.info("aboutToAppear")
245e41f4b71Sopenharmony_ci      // Initialize the web NDK.
246e41f4b71Sopenharmony_ci      testNapi.nativeWebInit(this.webTag);
247e41f4b71Sopenharmony_ci    }
248e41f4b71Sopenharmony_ci
249e41f4b71Sopenharmony_ci    build() {
250e41f4b71Sopenharmony_ci      Column() {
251e41f4b71Sopenharmony_ci        Row() {
252e41f4b71Sopenharmony_ci          Button('runJS hello')
253e41f4b71Sopenharmony_ci            .fontSize(12)
254e41f4b71Sopenharmony_ci            .onClick(() => {
255e41f4b71Sopenharmony_ci              testNapi.runJavaScript(this.webTag, "runJSRetStr(\"" + "hello" + "\")");
256e41f4b71Sopenharmony_ci            })
257e41f4b71Sopenharmony_ci        }.height('20%')
258e41f4b71Sopenharmony_ci
259e41f4b71Sopenharmony_ci        Row() {
260e41f4b71Sopenharmony_ci          Web({ src: $rawfile('runJS.html'), controller: this.controller })
261e41f4b71Sopenharmony_ci            .javaScriptAccess(true)
262e41f4b71Sopenharmony_ci            .fileAccess(true)
263e41f4b71Sopenharmony_ci            .onControllerAttached(() => {
264e41f4b71Sopenharmony_ci              console.error("ndk onControllerAttached webId: " + this.controller.getWebId());
265e41f4b71Sopenharmony_ci            })
266e41f4b71Sopenharmony_ci        }.height('80%')
267e41f4b71Sopenharmony_ci      }
268e41f4b71Sopenharmony_ci    }
269e41f4b71Sopenharmony_ci  }
270e41f4b71Sopenharmony_ci  ```
271e41f4b71Sopenharmony_ci
272e41f4b71Sopenharmony_ci* The ArkTS APIs exposed on the NAPI side in **entry/src/main/cpp/types/libentry/index.d.ts**:
273e41f4b71Sopenharmony_ci
274e41f4b71Sopenharmony_ci  ```javascript
275e41f4b71Sopenharmony_ci  export const nativeWebInit: (webName: string) => void;
276e41f4b71Sopenharmony_ci  export const runJavaScript: (webName: string, jsCode: string) => void;
277e41f4b71Sopenharmony_ci  ```
278e41f4b71Sopenharmony_ci
279e41f4b71Sopenharmony_ci* Compilation configuration on the NAPI Side in **entry/src/main/cpp/CMakeLists.txt**:
280e41f4b71Sopenharmony_ci
281e41f4b71Sopenharmony_ci  ```c++
282e41f4b71Sopenharmony_ci  # the minimum version of CMake.
283e41f4b71Sopenharmony_ci  cmake_minimum_required(VERSION 3.4.1)
284e41f4b71Sopenharmony_ci  project(NDKJSBridg)
285e41f4b71Sopenharmony_ci
286e41f4b71Sopenharmony_ci  set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})
287e41f4b71Sopenharmony_ci
288e41f4b71Sopenharmony_ci  if(DEFINED PACKAGE_FIND_FILE)
289e41f4b71Sopenharmony_ci      include(${PACKAGE_FIND_FILE})
290e41f4b71Sopenharmony_ci  endif()
291e41f4b71Sopenharmony_ci
292e41f4b71Sopenharmony_ci  include_directories(${NATIVERENDER_ROOT_PATH}
293e41f4b71Sopenharmony_ci                      ${NATIVERENDER_ROOT_PATH}/include)
294e41f4b71Sopenharmony_ci
295e41f4b71Sopenharmony_ci  add_library(entry SHARED hello.cpp jsbridge_object.cpp)
296e41f4b71Sopenharmony_ci
297e41f4b71Sopenharmony_ci  find_library(
298e41f4b71Sopenharmony_ci      # Sets the name of the path variable.
299e41f4b71Sopenharmony_ci      hilog-lib
300e41f4b71Sopenharmony_ci      # Specifies the name of the NDK library that
301e41f4b71Sopenharmony_ci      # you want CMake to locate.
302e41f4b71Sopenharmony_ci      hilog_ndk.z
303e41f4b71Sopenharmony_ci  )
304e41f4b71Sopenharmony_ci
305e41f4b71Sopenharmony_ci  target_link_libraries(entry PUBLIC libace_napi.z.so ${hilog-lib} libohweb.so)
306e41f4b71Sopenharmony_ci  ```
307e41f4b71Sopenharmony_ci
308e41f4b71Sopenharmony_ci* NAPI layer code in **entry/src/main/cpp/hello.cpp**:
309e41f4b71Sopenharmony_ci
310e41f4b71Sopenharmony_ci  ```c++
311e41f4b71Sopenharmony_ci  #include "napi/native_api.h"
312e41f4b71Sopenharmony_ci  #include <bits/alltypes.h>
313e41f4b71Sopenharmony_ci  #include <memory>
314e41f4b71Sopenharmony_ci  #include <string>
315e41f4b71Sopenharmony_ci  #include <sys/types.h>
316e41f4b71Sopenharmony_ci  #include <thread>
317e41f4b71Sopenharmony_ci
318e41f4b71Sopenharmony_ci  #include "hilog/log.h"
319e41f4b71Sopenharmony_ci  #include "web/arkweb_interface.h"
320e41f4b71Sopenharmony_ci  #include "jsbridge_object.h"
321e41f4b71Sopenharmony_ci
322e41f4b71Sopenharmony_ci  constexpr unsigned int LOG_PRINT_DOMAIN = 0xFF00;
323e41f4b71Sopenharmony_ci  std::shared_ptr<JSBridgeObject> jsbridge_object_ptr = nullptr;
324e41f4b71Sopenharmony_ci  static ArkWeb_ControllerAPI *controller = nullptr;
325e41f4b71Sopenharmony_ci  static ArkWeb_ComponentAPI *component = nullptr;
326e41f4b71Sopenharmony_ci
327e41f4b71Sopenharmony_ci  // Send the JS code to the HTML5 side for execution and obtain the execution result through a callback.
328e41f4b71Sopenharmony_ci  static void RunJavaScriptCallback(const char *webTag, const char *result, void *userData) {
329e41f4b71Sopenharmony_ci      OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "ndk RunJavaScriptCallback webTag:%{public}s", webTag);
330e41f4b71Sopenharmony_ci      if (!userData) {
331e41f4b71Sopenharmony_ci          OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "ndk RunJavaScriptCallback userData is nullptr");
332e41f4b71Sopenharmony_ci          return;
333e41f4b71Sopenharmony_ci      }
334e41f4b71Sopenharmony_ci      std::weak_ptr<JSBridgeObject> jsb_weak_ptr = *static_cast<std::weak_ptr<JSBridgeObject> *>(userData);
335e41f4b71Sopenharmony_ci      if (auto jsb_ptr = jsb_weak_ptr.lock()) {
336e41f4b71Sopenharmony_ci          jsb_ptr->RunJavaScriptCallback(result);
337e41f4b71Sopenharmony_ci      } else {
338e41f4b71Sopenharmony_ci          OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb",
339e41f4b71Sopenharmony_ci                       "ndk RunJavaScriptCallback jsb_weak_ptr lock failed");
340e41f4b71Sopenharmony_ci      }
341e41f4b71Sopenharmony_ci  }
342e41f4b71Sopenharmony_ci
343e41f4b71Sopenharmony_ci  // This example registers one object and two methods.
344e41f4b71Sopenharmony_ci  static void ProxyMethod1(const char *webTag, const ArkWeb_JavaScriptBridgeData *dataArray, size_t arraySize, void *userData) {
345e41f4b71Sopenharmony_ci      OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "ndk ProxyMethod1 webTag:%{public}s", webTag);
346e41f4b71Sopenharmony_ci      if (!userData) {
347e41f4b71Sopenharmony_ci          OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "ndk ProxyMethod1 userData is nullptr");
348e41f4b71Sopenharmony_ci          return;
349e41f4b71Sopenharmony_ci      }
350e41f4b71Sopenharmony_ci      std::weak_ptr<JSBridgeObject> jsb_weak_ptr = *static_cast<std::weak_ptr<JSBridgeObject> *>(userData);
351e41f4b71Sopenharmony_ci      if (auto jsb_ptr = jsb_weak_ptr.lock()) {
352e41f4b71Sopenharmony_ci          jsb_ptr->ProxyMethod1(dataArray, arraySize);
353e41f4b71Sopenharmony_ci      } else {
354e41f4b71Sopenharmony_ci          OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "ndk ProxyMethod1 jsb_weak_ptr lock failed");
355e41f4b71Sopenharmony_ci      }
356e41f4b71Sopenharmony_ci  }
357e41f4b71Sopenharmony_ci
358e41f4b71Sopenharmony_ci  static void ProxyMethod2(const char *webTag, const ArkWeb_JavaScriptBridgeData *dataArray, size_t arraySize, void *userData) {
359e41f4b71Sopenharmony_ci      OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "ndk ProxyMethod2 webTag:%{public}s", webTag);
360e41f4b71Sopenharmony_ci      if (!userData) {
361e41f4b71Sopenharmony_ci          OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "ndk ProxyMethod2 userData is nullptr");
362e41f4b71Sopenharmony_ci          return;
363e41f4b71Sopenharmony_ci      }
364e41f4b71Sopenharmony_ci      std::weak_ptr<JSBridgeObject> jsb_weak_ptr = *static_cast<std::weak_ptr<JSBridgeObject> *>(userData);
365e41f4b71Sopenharmony_ci
366e41f4b71Sopenharmony_ci      std::string jsCode = "runJSRetStr()";
367e41f4b71Sopenharmony_ci      ArkWeb_JavaScriptObject object = {(uint8_t *)jsCode.c_str(), jsCode.size(),
368e41f4b71Sopenharmony_ci                                       &JSBridgeObject::StaticRunJavaScriptCallback,
369e41f4b71Sopenharmony_ci                                       static_cast<void *>(jsbridge_object_ptr->GetWeakPtr())};
370e41f4b71Sopenharmony_ci      controller->runJavaScript(webTag, &object);
371e41f4b71Sopenharmony_ci
372e41f4b71Sopenharmony_ci      if (auto jsb_ptr = jsb_weak_ptr.lock()) {
373e41f4b71Sopenharmony_ci          jsb_ptr->ProxyMethod2(dataArray, arraySize);
374e41f4b71Sopenharmony_ci      } else {
375e41f4b71Sopenharmony_ci          OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "ndk ProxyMethod2 jsb_weak_ptr lock failed");
376e41f4b71Sopenharmony_ci      }
377e41f4b71Sopenharmony_ci  }
378e41f4b71Sopenharmony_ci
379e41f4b71Sopenharmony_ci  void ValidCallback(const char *webTag, void *userData) {
380e41f4b71Sopenharmony_ci      OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "ndk ValidCallback webTag: %{public}s", webTag);
381e41f4b71Sopenharmony_ci      if (!userData) {
382e41f4b71Sopenharmony_ci          OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "ndk ValidCallback userData is nullptr");
383e41f4b71Sopenharmony_ci          return;
384e41f4b71Sopenharmony_ci      }
385e41f4b71Sopenharmony_ci      std::weak_ptr<JSBridgeObject> jsb_weak_ptr = *static_cast<std::weak_ptr<JSBridgeObject> *>(userData);
386e41f4b71Sopenharmony_ci      if (auto jsb_ptr = jsb_weak_ptr.lock()) {
387e41f4b71Sopenharmony_ci          jsb_ptr->SaySomething("ValidCallback");
388e41f4b71Sopenharmony_ci      } else {
389e41f4b71Sopenharmony_ci          OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "ndk ValidCallback jsb_weak_ptr lock failed");
390e41f4b71Sopenharmony_ci      }
391e41f4b71Sopenharmony_ci
392e41f4b71Sopenharmony_ci      // Register an object.
393e41f4b71Sopenharmony_ci      OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "ndk RegisterJavaScriptProxy begin");
394e41f4b71Sopenharmony_ci      ArkWeb_ProxyMethod method1 = {"method1", ProxyMethod1, static_cast<void *>(jsbridge_object_ptr->GetWeakPtr())};
395e41f4b71Sopenharmony_ci      ArkWeb_ProxyMethod method2 = {"method2", ProxyMethod2, static_cast<void *>(jsbridge_object_ptr->GetWeakPtr())};
396e41f4b71Sopenharmony_ci      ArkWeb_ProxyMethod methodList[2] = {method1, method2};
397e41f4b71Sopenharmony_ci      // Invoke the native API to register the object.
398e41f4b71Sopenharmony_ci      // In this case, you can use proxy.method1 and proxy.method2 to call ProxyMethod1 and ProxyMethod2 in this file on the HTML5 side.
399e41f4b71Sopenharmony_ci      ArkWeb_ProxyObject proxyObject = {"ndkProxy", methodList, 2};
400e41f4b71Sopenharmony_ci      controller->registerJavaScriptProxy(webTag, &proxyObject);
401e41f4b71Sopenharmony_ci
402e41f4b71Sopenharmony_ci      OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "ndk RegisterJavaScriptProxy end");
403e41f4b71Sopenharmony_ci  }
404e41f4b71Sopenharmony_ci
405e41f4b71Sopenharmony_ci  void LoadStartCallback(const char *webTag, void *userData) {
406e41f4b71Sopenharmony_ci      OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "ndk LoadStartCallback webTag: %{public}s", webTag);
407e41f4b71Sopenharmony_ci      if (!userData) {
408e41f4b71Sopenharmony_ci          OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "ndk LoadStartCallback userData is nullptr");
409e41f4b71Sopenharmony_ci          return;
410e41f4b71Sopenharmony_ci      }
411e41f4b71Sopenharmony_ci      std::weak_ptr<JSBridgeObject> jsb_weak_ptr = *static_cast<std::weak_ptr<JSBridgeObject> *>(userData);
412e41f4b71Sopenharmony_ci      if (auto jsb_ptr = jsb_weak_ptr.lock()) {
413e41f4b71Sopenharmony_ci          jsb_ptr->SaySomething("LoadStartCallback");
414e41f4b71Sopenharmony_ci      } else {
415e41f4b71Sopenharmony_ci          OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "ndk LoadStartCallback jsb_weak_ptr lock failed");
416e41f4b71Sopenharmony_ci      }
417e41f4b71Sopenharmony_ci  }
418e41f4b71Sopenharmony_ci
419e41f4b71Sopenharmony_ci  void LoadEndCallback(const char *webTag, void *userData) {
420e41f4b71Sopenharmony_ci      OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "ndk LoadEndCallback webTag: %{public}s", webTag);
421e41f4b71Sopenharmony_ci      if (!userData) {
422e41f4b71Sopenharmony_ci          OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "ndk LoadEndCallback userData is nullptr");
423e41f4b71Sopenharmony_ci          return;
424e41f4b71Sopenharmony_ci      }
425e41f4b71Sopenharmony_ci      std::weak_ptr<JSBridgeObject> jsb_weak_ptr = *static_cast<std::weak_ptr<JSBridgeObject> *>(userData);
426e41f4b71Sopenharmony_ci      if (auto jsb_ptr = jsb_weak_ptr.lock()) {
427e41f4b71Sopenharmony_ci          jsb_ptr->SaySomething("LoadEndCallback");
428e41f4b71Sopenharmony_ci      } else {
429e41f4b71Sopenharmony_ci          OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "ndk LoadEndCallback jsb_weak_ptr lock failed");
430e41f4b71Sopenharmony_ci      }
431e41f4b71Sopenharmony_ci  }
432e41f4b71Sopenharmony_ci
433e41f4b71Sopenharmony_ci  void DestroyCallback(const char *webTag, void *userData) {
434e41f4b71Sopenharmony_ci      OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "ndk DestoryCallback webTag: %{public}s", webTag);
435e41f4b71Sopenharmony_ci      if (!userData) {
436e41f4b71Sopenharmony_ci          OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "ndk DestroyCallback userData is nullptr");
437e41f4b71Sopenharmony_ci          return;
438e41f4b71Sopenharmony_ci      }
439e41f4b71Sopenharmony_ci      std::weak_ptr<JSBridgeObject> jsb_weak_ptr = *static_cast<std::weak_ptr<JSBridgeObject> *>(userData);
440e41f4b71Sopenharmony_ci      if (auto jsb_ptr = jsb_weak_ptr.lock()) {
441e41f4b71Sopenharmony_ci          jsb_ptr->SaySomething("DestroyCallback");
442e41f4b71Sopenharmony_ci      } else {
443e41f4b71Sopenharmony_ci          OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "ndk DestroyCallback jsb_weak_ptr lock failed");
444e41f4b71Sopenharmony_ci      }
445e41f4b71Sopenharmony_ci  }
446e41f4b71Sopenharmony_ci
447e41f4b71Sopenharmony_ci  void SetComponentCallback(ArkWeb_ComponentAPI * component, const char* webTagValue) {
448e41f4b71Sopenharmony_ci      if (!ARKWEB_MEMBER_MISSING(component, onControllerAttached)) {
449e41f4b71Sopenharmony_ci          component->onControllerAttached(webTagValue, ValidCallback,
450e41f4b71Sopenharmony_ci                                          static_cast<void *>(jsbridge_object_ptr->GetWeakPtr()));
451e41f4b71Sopenharmony_ci      } else {
452e41f4b71Sopenharmony_ci          OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "ArkWeb", "component onControllerAttached func not exist");
453e41f4b71Sopenharmony_ci      }
454e41f4b71Sopenharmony_ci
455e41f4b71Sopenharmony_ci      if (!ARKWEB_MEMBER_MISSING(component, onPageBegin)) {
456e41f4b71Sopenharmony_ci          component->onPageBegin(webTagValue, LoadStartCallback,
457e41f4b71Sopenharmony_ci                                          static_cast<void *>(jsbridge_object_ptr->GetWeakPtr()));
458e41f4b71Sopenharmony_ci      } else {
459e41f4b71Sopenharmony_ci          OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "ArkWeb", "component onPageBegin func not exist");
460e41f4b71Sopenharmony_ci      }
461e41f4b71Sopenharmony_ci
462e41f4b71Sopenharmony_ci      if (!ARKWEB_MEMBER_MISSING(component, onPageEnd)) {
463e41f4b71Sopenharmony_ci          component->onPageEnd(webTagValue, LoadEndCallback,
464e41f4b71Sopenharmony_ci                                          static_cast<void *>(jsbridge_object_ptr->GetWeakPtr()));
465e41f4b71Sopenharmony_ci      } else {
466e41f4b71Sopenharmony_ci          OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "ArkWeb", "component onPageEnd func not exist");
467e41f4b71Sopenharmony_ci      }
468e41f4b71Sopenharmony_ci
469e41f4b71Sopenharmony_ci      if (!ARKWEB_MEMBER_MISSING(component, onDestroy)) {
470e41f4b71Sopenharmony_ci          component->onDestroy(webTagValue, DestroyCallback,
471e41f4b71Sopenharmony_ci                                          static_cast<void *>(jsbridge_object_ptr->GetWeakPtr()));
472e41f4b71Sopenharmony_ci      } else {
473e41f4b71Sopenharmony_ci          OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "ArkWeb", "component onDestroy func not exist");
474e41f4b71Sopenharmony_ci      }
475e41f4b71Sopenharmony_ci  }
476e41f4b71Sopenharmony_ci
477e41f4b71Sopenharmony_ci  // Parse and store the webTag.
478e41f4b71Sopenharmony_ci  static napi_value NativeWebInit(napi_env env, napi_callback_info info) {
479e41f4b71Sopenharmony_ci      OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "ndk NativeWebInit start");
480e41f4b71Sopenharmony_ci      size_t argc = 1;
481e41f4b71Sopenharmony_ci      napi_value args[1] = {nullptr};
482e41f4b71Sopenharmony_ci      napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
483e41f4b71Sopenharmony_ci      // Obtain the first parameter webTag.
484e41f4b71Sopenharmony_ci      size_t webTagSize = 0;
485e41f4b71Sopenharmony_ci      napi_get_value_string_utf8(env, args[0], nullptr, 0, &webTagSize);
486e41f4b71Sopenharmony_ci      char *webTagValue = new (std::nothrow) char[webTagSize + 1];
487e41f4b71Sopenharmony_ci      size_t webTagLength = 0;
488e41f4b71Sopenharmony_ci      napi_get_value_string_utf8(env, args[0], webTagValue, webTagSize + 1, &webTagLength);
489e41f4b71Sopenharmony_ci      OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "ArkWeb", "ndk NativeWebInit webTag:%{public}s", webTagValue);
490e41f4b71Sopenharmony_ci
491e41f4b71Sopenharmony_ci      // Save the webTag in the instance object.
492e41f4b71Sopenharmony_ci      jsbridge_object_ptr = std::make_shared<JSBridgeObject>(webTagValue);
493e41f4b71Sopenharmony_ci      if (jsbridge_object_ptr)
494e41f4b71Sopenharmony_ci          jsbridge_object_ptr->Init();
495e41f4b71Sopenharmony_ci
496e41f4b71Sopenharmony_ci      controller = reinterpret_cast<ArkWeb_ControllerAPI *>(OH_ArkWeb_GetNativeAPI(ARKWEB_NATIVE_CONTROLLER));
497e41f4b71Sopenharmony_ci      component = reinterpret_cast<ArkWeb_ComponentAPI *>(OH_ArkWeb_GetNativeAPI(ARKWEB_NATIVE_COMPONENT));
498e41f4b71Sopenharmony_ci      SetComponentCallback(component, webTagValue);
499e41f4b71Sopenharmony_ci
500e41f4b71Sopenharmony_ci      OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "ndk NativeWebInit end");
501e41f4b71Sopenharmony_ci      return nullptr;
502e41f4b71Sopenharmony_ci  }
503e41f4b71Sopenharmony_ci
504e41f4b71Sopenharmony_ci  // Send the JS code to the HTML5 side for execution.
505e41f4b71Sopenharmony_ci  static napi_value RunJavaScript(napi_env env, napi_callback_info info) {
506e41f4b71Sopenharmony_ci      size_t argc = 2;
507e41f4b71Sopenharmony_ci      napi_value args[2] = {nullptr};
508e41f4b71Sopenharmony_ci      napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
509e41f4b71Sopenharmony_ci
510e41f4b71Sopenharmony_ci      // Obtain the first parameter webTag.
511e41f4b71Sopenharmony_ci      size_t webTagSize = 0;
512e41f4b71Sopenharmony_ci      napi_get_value_string_utf8(env, args[0], nullptr, 0, &webTagSize);
513e41f4b71Sopenharmony_ci      char *webTagValue = new (std::nothrow) char[webTagSize + 1];
514e41f4b71Sopenharmony_ci      size_t webTagLength = 0;
515e41f4b71Sopenharmony_ci      napi_get_value_string_utf8(env, args[0], webTagValue, webTagSize + 1, &webTagLength);
516e41f4b71Sopenharmony_ci      OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "ndk OH_NativeArkWeb_RunJavaScript webTag:%{public}s",
517e41f4b71Sopenharmony_ci                   webTagValue);
518e41f4b71Sopenharmony_ci
519e41f4b71Sopenharmony_ci      // Obtain the second parameter jsCode.
520e41f4b71Sopenharmony_ci      size_t bufferSize = 0;
521e41f4b71Sopenharmony_ci      napi_get_value_string_utf8(env, args[1], nullptr, 0, &bufferSize);
522e41f4b71Sopenharmony_ci      char *jsCode = new (std::nothrow) char[bufferSize + 1];
523e41f4b71Sopenharmony_ci      size_t byteLength = 0;
524e41f4b71Sopenharmony_ci      napi_get_value_string_utf8(env, args[1], jsCode, bufferSize + 1, &byteLength);
525e41f4b71Sopenharmony_ci
526e41f4b71Sopenharmony_ci      OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb",
527e41f4b71Sopenharmony_ci                   "ndk OH_NativeArkWeb_RunJavaScript jsCode len:%{public}zu", strlen(jsCode));
528e41f4b71Sopenharmony_ci
529e41f4b71Sopenharmony_ci      // Construct a struct executed in runJS.
530e41f4b71Sopenharmony_ci      ArkWeb_JavaScriptObject object = {(uint8_t *)jsCode, bufferSize, &JSBridgeObject::StaticRunJavaScriptCallback,
531e41f4b71Sopenharmony_ci                                       static_cast<void *>(jsbridge_object_ptr->GetWeakPtr())};
532e41f4b71Sopenharmony_ci      controller->runJavaScript(webTagValue, &object);
533e41f4b71Sopenharmony_ci      return nullptr;
534e41f4b71Sopenharmony_ci  }
535e41f4b71Sopenharmony_ci
536e41f4b71Sopenharmony_ci  EXTERN_C_START
537e41f4b71Sopenharmony_ci  static napi_value Init(napi_env env, napi_value exports) {
538e41f4b71Sopenharmony_ci      napi_property_descriptor desc[] = {
539e41f4b71Sopenharmony_ci          {"nativeWebInit", nullptr, NativeWebInit, nullptr, nullptr, nullptr, napi_default, nullptr},
540e41f4b71Sopenharmony_ci          {"runJavaScript", nullptr, RunJavaScript, nullptr, nullptr, nullptr, napi_default, nullptr},
541e41f4b71Sopenharmony_ci      };
542e41f4b71Sopenharmony_ci      napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
543e41f4b71Sopenharmony_ci      return exports;
544e41f4b71Sopenharmony_ci  }
545e41f4b71Sopenharmony_ci  EXTERN_C_END
546e41f4b71Sopenharmony_ci
547e41f4b71Sopenharmony_ci  static napi_module demoModule = {
548e41f4b71Sopenharmony_ci      .nm_version = 1,
549e41f4b71Sopenharmony_ci      .nm_flags = 0,
550e41f4b71Sopenharmony_ci      .nm_filename = nullptr,
551e41f4b71Sopenharmony_ci      .nm_register_func = Init,
552e41f4b71Sopenharmony_ci      .nm_modname = "entry",
553e41f4b71Sopenharmony_ci      .nm_priv = ((void *)0),
554e41f4b71Sopenharmony_ci      .reserved = {0},
555e41f4b71Sopenharmony_ci  };
556e41f4b71Sopenharmony_ci
557e41f4b71Sopenharmony_ci  extern "C" __attribute__((constructor)) void RegisterEntryModule(void) { napi_module_register(&demoModule); }
558e41f4b71Sopenharmony_ci  ```
559e41f4b71Sopenharmony_ci
560e41f4b71Sopenharmony_ci* Native service codes in **entry/src/main/cpp/jsbridge_object.h** and **entry/src/main/cpp/jsbridge_object.cpp**:
561e41f4b71Sopenharmony_ci
562e41f4b71Sopenharmony_ci  ```c++
563e41f4b71Sopenharmony_ci  #include "web/arkweb_type.h"
564e41f4b71Sopenharmony_ci  #include <string>
565e41f4b71Sopenharmony_ci
566e41f4b71Sopenharmony_ci  class JSBridgeObject : public std::enable_shared_from_this<JSBridgeObject> {
567e41f4b71Sopenharmony_ci  public:
568e41f4b71Sopenharmony_ci      JSBridgeObject(const char* webTag);
569e41f4b71Sopenharmony_ci      ~JSBridgeObject() = default;
570e41f4b71Sopenharmony_ci      void Init();
571e41f4b71Sopenharmony_ci      std::weak_ptr<JSBridgeObject>* GetWeakPtr();
572e41f4b71Sopenharmony_ci      static void StaticRunJavaScriptCallback(const char *webTag, const ArkWeb_JavaScriptBridgeData *data, void *userData);
573e41f4b71Sopenharmony_ci      void RunJavaScriptCallback(const char *result);
574e41f4b71Sopenharmony_ci      void ProxyMethod1(const ArkWeb_JavaScriptBridgeData *dataArray, int32_t arraySize);
575e41f4b71Sopenharmony_ci      void ProxyMethod2(const ArkWeb_JavaScriptBridgeData *dataArray, int32_t arraySize);
576e41f4b71Sopenharmony_ci      void SaySomething(const char* say);
577e41f4b71Sopenharmony_ci
578e41f4b71Sopenharmony_ci  private:
579e41f4b71Sopenharmony_ci      std::string webTag_;
580e41f4b71Sopenharmony_ci      std::weak_ptr<JSBridgeObject> weak_ptr_;
581e41f4b71Sopenharmony_ci  };
582e41f4b71Sopenharmony_ci  ```
583e41f4b71Sopenharmony_ci
584e41f4b71Sopenharmony_ci  ```c++
585e41f4b71Sopenharmony_ci  #include "jsbridge_object.h"
586e41f4b71Sopenharmony_ci
587e41f4b71Sopenharmony_ci  #include "hilog/log.h"
588e41f4b71Sopenharmony_ci
589e41f4b71Sopenharmony_ci  constexpr unsigned int LOG_PRINT_DOMAIN = 0xFF00;
590e41f4b71Sopenharmony_ci
591e41f4b71Sopenharmony_ci  JSBridgeObject::JSBridgeObject(const char *webTag) : webTag_(webTag) {}
592e41f4b71Sopenharmony_ci
593e41f4b71Sopenharmony_ci  void JSBridgeObject::Init() { weak_ptr_ = shared_from_this(); }
594e41f4b71Sopenharmony_ci
595e41f4b71Sopenharmony_ci  std::weak_ptr<JSBridgeObject> *JSBridgeObject::GetWeakPtr() { return &weak_ptr_; }
596e41f4b71Sopenharmony_ci
597e41f4b71Sopenharmony_ci  void JSBridgeObject::StaticRunJavaScriptCallback(const char *webTag, const ArkWeb_JavaScriptBridgeData *data,
598e41f4b71Sopenharmony_ci                                                   void *userData) {
599e41f4b71Sopenharmony_ci      OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb",
600e41f4b71Sopenharmony_ci                   "JSBridgeObject StaticRunJavaScriptCallback webTag:%{public}s", webTag);
601e41f4b71Sopenharmony_ci      if (!userData) {
602e41f4b71Sopenharmony_ci          OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb",
603e41f4b71Sopenharmony_ci                       "JSBridgeObject StaticRunJavaScriptCallback userData is nullptr");
604e41f4b71Sopenharmony_ci          return;
605e41f4b71Sopenharmony_ci      }
606e41f4b71Sopenharmony_ci      std::weak_ptr<JSBridgeObject> jsb_weak_ptr = *static_cast<std::weak_ptr<JSBridgeObject> *>(userData);
607e41f4b71Sopenharmony_ci      if (auto jsb_ptr = jsb_weak_ptr.lock()) {
608e41f4b71Sopenharmony_ci          std::string result((char *)data->buffer, data->size);
609e41f4b71Sopenharmony_ci          jsb_ptr->RunJavaScriptCallback(result.c_str());
610e41f4b71Sopenharmony_ci      } else {
611e41f4b71Sopenharmony_ci          OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb",
612e41f4b71Sopenharmony_ci                       "JSBridgeObject StaticRunJavaScriptCallback jsb_weak_ptr lock failed");
613e41f4b71Sopenharmony_ci      }
614e41f4b71Sopenharmony_ci  }
615e41f4b71Sopenharmony_ci
616e41f4b71Sopenharmony_ci  void JSBridgeObject::RunJavaScriptCallback(const char *result) {
617e41f4b71Sopenharmony_ci      OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb",
618e41f4b71Sopenharmony_ci                   "JSBridgeObject OH_NativeArkWeb_RunJavaScript result:%{public}s", result);
619e41f4b71Sopenharmony_ci  }
620e41f4b71Sopenharmony_ci
621e41f4b71Sopenharmony_ci  void JSBridgeObject::ProxyMethod1(const ArkWeb_JavaScriptBridgeData *dataArray, int32_t arraySize) {
622e41f4b71Sopenharmony_ci      OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "JSBridgeObject ProxyMethod1 argc:%{public}d",
623e41f4b71Sopenharmony_ci                   arraySize);
624e41f4b71Sopenharmony_ci      for (int i = 0; i < arraySize; i++) {
625e41f4b71Sopenharmony_ci          std::string result((char *)dataArray[i].buffer, dataArray[i].size);
626e41f4b71Sopenharmony_ci          OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb",
627e41f4b71Sopenharmony_ci                       "JSBridgeObject ProxyMethod1 argv[%{public}d]:%{public}s, size:%{public}d", i, result.c_str(),
628e41f4b71Sopenharmony_ci                       dataArray[i].size);
629e41f4b71Sopenharmony_ci      }
630e41f4b71Sopenharmony_ci  }
631e41f4b71Sopenharmony_ci
632e41f4b71Sopenharmony_ci  void JSBridgeObject::ProxyMethod2(const ArkWeb_JavaScriptBridgeData *dataArray, int32_t arraySize) {
633e41f4b71Sopenharmony_ci      OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "JSBridgeObject ProxyMethod2 argc:%{public}d",
634e41f4b71Sopenharmony_ci                   arraySize);
635e41f4b71Sopenharmony_ci      for (int i = 0; i < arraySize; i++) {
636e41f4b71Sopenharmony_ci          std::string result((char *)dataArray[i].buffer, dataArray[i].size);
637e41f4b71Sopenharmony_ci          OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb",
638e41f4b71Sopenharmony_ci                       "JSBridgeObject ProxyMethod2 argv[%{public}d]:%{public}s, size:%{public}d", i, result.c_str(),
639e41f4b71Sopenharmony_ci                       dataArray[i].size);
640e41f4b71Sopenharmony_ci      }
641e41f4b71Sopenharmony_ci  }
642e41f4b71Sopenharmony_ci
643e41f4b71Sopenharmony_ci  void JSBridgeObject::SaySomething(const char *say) {
644e41f4b71Sopenharmony_ci      OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "JSBridgeObject SaySomething argc:%{public}s", say);
645e41f4b71Sopenharmony_ci  }
646e41f4b71Sopenharmony_ci  ```
647