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  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  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