建立应用侧与前端页面数据通道(C/C++)
前端页面和应用侧之间可以使用Native方法实现两端通信(以下简称Native PostWebMessage),可解决ArkTS环境的冗余切换,同时允许发送消息、回调在非UI线程上运行,避免造成UI阻塞。当前只支持string和buffer数据类型。
适用的应用架构
应用使用ArkTS、C++语言混合开发,或本身应用架构较贴近于小程序架构,自带C++侧环境,推荐使用ArkWeb在Native侧提供的ArkWeb_ControllerAPI、ArkWeb_WebMessageAPI、ArkWeb_WebMessagePortAPI实现PostWebMessage功能。

上图展示了具有普遍适用性的小程序的通用架构。在这一架构中,逻辑层依赖于应用程序自带的JavaScript运行时,该运行时在一个已有的C++环境中运行。通过Native接口,逻辑层能够直接在C++环境中与视图层(其中ArkWeb充当渲染器)进行通信,无需回退至ArkTS环境使用ArkTS PostWebMessage接口。
左图是使用ArkTS PostWebMessage接口构建小程序的方案,如红框所示,应用需要先调用到ArkTS环境,再调用到C++环境。右图是使用Native PostWebMessage接口构建小程序的方案,不需要ArkTS环境和C++环境的切换,执行效率更高。

使用Native接口实现PostWebMessage通信
使用Native接口绑定ArkWeb
-
ArkWeb组件声明在ArkTS侧,需要用户自定义一个标识webTag,并将webTag通过Node-API传至应用C++侧。后续ArkWeb Native接口使用时,均需webTag作为对应组件的唯一标识。
-
ArkTS侧
import { webview } from '@kit.ArkWeb';// 自定义webTag,在WebviewController创建时作为入参传入,建立controller与webTag的映射关系webTag: string = 'ArkWeb1';controller: webview.WebviewController = new webview.WebviewController(this.webTag);// ...// aboutToAppear中将webTag通过Node-API接口传入C++侧,作为C++侧ArkWeb组件的唯一标识aboutToAppear() {console.info("aboutToAppear")// 初始化web ndktestNapi.nativeWebInit(this.webTag);}// ...
使用Native接口获取API结构体
ArkWeb Native侧需先获取API结构体,才能调用结构体里的Native API。ArkWeb Native侧API通过函数OH_ArkWeb_GetNativeAPI获取,根据入参type不同,可获取对应的函数指针结构体。其中本指导涉及ArkWeb_ControllerAPI、ArkWeb_WebMessageAPI、ArkWeb_WebMessagePortAPI。
static ArkWeb_ControllerAPI *controller = nullptr;
static ArkWeb_WebMessagePortAPI *webMessagePort = nullptr;
static ArkWeb_WebMessageAPI *webMessage = nullptr;
// ...
controller = reinterpret_cast<ArkWeb_ControllerAPI *>(OH_ArkWeb_GetNativeAPI(ARKWEB_NATIVE_CONTROLLER));
webMessagePort =
reinterpret_cast<ArkWeb_WebMessagePortAPI *>(OH_ArkWeb_GetNativeAPI(ARKWEB_NATIVE_WEB_MESSAGE_PORT));
webMessage = reinterpret_cast<ArkWeb_WebMessageAPI *>(OH_ArkWeb_GetNativeAPI(ARKWEB_NATIVE_WEB_MESSAGE));
完整示例
在调用API前建议通过ARKWEB_MEMBER_MISSING校验该函数结构体是否有对应函数指针,避免SDK与设备ROM不匹配导致crash问题。createWebMessagePorts、postWebMessage、close需运行在UI线程。
-
前端页面代码
<!-- entry/src/main/resources/rawfile/index.html --><!-- index.html --><!DOCTYPE html><html lang="en-gb"><body><h1>etsRunJavaScriptExt测试demo</h1><h1 id="h1"></h1><h3 id="msg">Receive string:</h3><h3 id="msg2">Receive arraybuffer:</h3></body><script type="text/javascript">var h5Port;window.addEventListener('message', function (event) {if (event.data == 'init_web_messageport') {const port = event.ports[0]; // 1. 保存从应用侧发送过来的端口。if (port) {console.info("hwd In html got message");h5Port = port;port.onmessage = function (event) {console.info("hwd In html got message");// 2. 接收应用侧发送过来的消息.var result = event.data;var type_s = typeof (result)switch (type_s) {case "object":if (result instanceof ArrayBuffer) {type_s = "ArrayBuffer";var view = new Uint8Array(result);const decoder = new TextDecoder('utf-8');result = decoder.decode(result);} else if (result instanceof Error) {type_s = "Error";} else if (result instanceof Array) {type_s = "Array";}break;default:break;}console.info("H5 recv type: " + type_s + "\nH5 recv result: " + result)document.getElementById("msg").innerHTML = "recv type: " + type_s;document.getElementById("msg2").innerHTML = "recv value: " + result;}h5Port.onmessageerror = (event) => {console.error(`hwd In html Error receiving message: ${event}`);};}}})window.onerror = function(message, url, line, column, error) {console.info("JavaScript Error: " + message + " on line " + line + " in " + url);document.getElementById("h1").innerHTML = "执行函数失败"};// 3. 使用h5Port向应用侧发送消息。function postStringToApp() {if (h5Port) {h5Port.postMessage("send string from H5");} else {console.error("In html h5port is null, please init first");}}function postBufferToApp() {if (h5Port) {const str = "Hello, World!";const encoder = new TextEncoder();const uint8Array = encoder.encode(str);h5Port.postMessage(uint8Array.buffer);} else {console.error("In html h5port is null, please init first");}}function postJsonToApp() {if (h5Port) {var e = {"json": "json"};h5Port.postMessage(e);} else {console.error("In html h5port is null, please init first");}}function postArrayStringToApp() {if (h5Port) {h5Port.postMessage(["1", "2", "3"]);} else {console.error("In html h5port is null, please init first");}}function postNumberToApp() {if (h5Port) {h5Port.postMessage(123);} else {console.error("In html h5port is null, please init first");}}class MyClass {constructor() {// 构造器this.myProperty = 'Hello, World!';}myMethod() {// 实例方法console.info(this.myProperty);}static myStaticMethod() {// 静态方法console.info('This is a static method.');}}function postObjectToApp() {if (h5Port) {h5Port.postMessage(new MyClass());} else {console.error("In html h5port is null, please init first");}}</script></html> -
ArkTS侧代码
import testNapi from 'libentry.so';import { webview } from '@kit.ArkWeb';import { BusinessError } from '@kit.BasicServicesKit';@Entry@Componentstruct Index {@State webTag: string = 'postMessage';controller: webview.WebviewController = new webview.WebviewController(this.webTag);@State h5Log: string = 'Display received message send from HTML';aboutToAppear() {webview.WebviewController.setWebDebuggingAccess(true);// 初始化web Native Development KittestNapi.nativeWebInit(this.webTag);}aboutToDisAppear() {console.error('aboutToDisAppear');}build() {Scroll() {Column({ space: 10 }) {// 展示H5接收到的内容Text('H5_Side_Message_Display_From_App')TextArea({text: this.h5Log}).id('log_area').width('100%').height(100).border({ width: 1 })Text('App_Side_Button')Row() {Button('createNoControllerTagPort').id('create_no_tag_btn').onClick(() => {try {testNapi.createWebMessagePorts('noTag');} catch (error) {console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);}})Button('createPort').id('create_port_btn').onClick(() => {try {testNapi.createWebMessagePorts(this.webTag);} catch (error) {console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);}})}Row({ space: 10 }) {Button('setHandler').id('set_handler_btn').onClick(() => {try {testNapi.setMessageEventHandler(this.webTag);} catch (error) {console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);}})Button('setHandlerThread').id('set_handler_thread_btn').onClick(() => {try {testNapi.setMessageEventHandlerThread(this.webTag);} catch (error) {console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);}})}Row({ space: 10 }) {Button('SendString').id('send_string_btn').onClick(() => {try {this.h5Log = ''testNapi.postMessage(this.webTag);} catch (error) {console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);}})Button('SendStringThread').id('send_string_thread_btn').onClick(() => {try {this.h5Log = ''testNapi.postMessageThread(this.webTag);} catch (error) {console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);}})}Row({ space: 10 }) {Button('SendBuffer').id('send_buffer_btn').onClick(() => {try {this.h5Log = ''testNapi.postBufferMessage(this.webTag);} catch (error) {console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);}})Button('SendNone').id('send_none_btn').onClick(() => {try {this.h5Log = ''testNapi.postNoneMessage(this.webTag);} catch (error) {console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);}})}Row({ space: 10 }) {Button('closePort').id('close_port_btn').onClick(() => {try {testNapi.closeMessagePort(this.webTag);} catch (error) {console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);}})Button('destroyNullPort').id('destroy_null_btn').onClick(() => {try {testNapi.destroyNullMessagePort(this.webTag);} catch (error) {console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);}})Button('destroyPort').id('destroy_port_btn').onClick(() => {try {testNapi.destroyMessagePort(this.webTag);} catch (error) {console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);}})}.width('100%').padding(10).border({ width: 1 })Column({ space: 10 }) {Text('H5_Side_Send_Button')Row({ space: 10 }) {Button('H5String').id('h5_send_string_btn').onClick(() => {try {this.controller.runJavaScript('for(var i = 0; i < 2000; i++) postStringToApp()');} catch (error) {console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);}})Button('H5Buffer').id('h5_send_buffer_btn').onClick(() => {try {this.controller.runJavaScript('postBufferToApp()');} catch (error) {console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);}})Button('H5Number').id('h5_send_number_btn').onClick(() => {try {this.controller.runJavaScript('postNumberToApp()');} catch (error) {console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);}})}Row({ space: 10 }) {Button('H5Json').id('h5_send_json_btn').onClick(() => {try {this.controller.runJavaScript('postJsonToApp()');} catch (error) {console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);}})Button('H5Array').id('h5_send_array_btn').onClick(() => {try {this.controller.runJavaScript('postArrayStringToApp()');} catch (error) {console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);}})Button('H5Object').id('h5_send_object_btn').onClick(() => {try {this.controller.runJavaScript('postObjectToApp()');} catch (error) {console.error(`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);}})}}.width('100%').margin(10).padding(10).border({ width: 1 })Web({ src: $rawfile('index.html'), controller: this.controller }).onConsole((event) => {if (event) {let msg = event.message.getMessage();if (msg.startsWith('H5')) {this.h5Log = event.message.getMessage() + '\n' + this.h5Log;}}return false;})}}.height('100%').scrollable(ScrollDirection.Vertical).scrollBar(BarState.Off).edgeEffect(EdgeEffect.Spring)}} -
Node-API侧暴露ArkTS接口
// entry5/src/main/cpp/types/libentry5/index.d.tsexport const nativeWebInit: (webName: string) => void;export const createWebMessagePorts: (webName: string) => void;export const postMessage: (webName: string) => void;export const postNoneMessage: (webName: string) => void;export const setMessageEventHandler: (webName: string) => void;export const closeMessagePort: (webName: string) => void;export const destroyMessagePort: (webName: string) => void;export const postBufferMessage: (webName: string) => void;export const destroyNullMessagePort: (webName: string) => void;export const setMessageEventHandlerThread: (webName: string) => void;export const postMessageThread: (webName: string) => void; -
Node-API侧编译配置
# entry/src/main/cpp/CMakeLists.txt# the minimum version of CMake.cmake_minimum_required(VERSION 3.4.1)project(NDKPostMessage)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 hello.cpp)find_library(# Sets the name of the path variable.hilog-lib# Specifies the name of the NDK library that# you want CMake to locate.hilog_ndk.z)target_link_libraries(entry PUBLIC libace_napi.z.so ${hilog-lib} libohweb.so) -
Node-API层代码
#include "hilog/log.h"#include "napi/native_api.h"#include "web/arkweb_interface.h"#include <string>#include <thread>constexpr unsigned int LOG_PRINT_DOMAIN = 0xFF00;ArkWeb_ControllerAPI *controller = nullptr;ArkWeb_WebMessagePortAPI *webMessagePort = nullptr;ArkWeb_WebMessageAPI *webMessage = nullptr;size_t g_webMessagePortSize = 0;ArkWeb_WebMessagePortPtr *g_web_message_port_arr = nullptr;static void WebMessagePortCallback(const char *webTag, const ArkWeb_WebMessagePortPtr port, const ArkWeb_WebMessagePtr message, void *userData){OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb","Native Development Kit WebMessagePortCallback webTag:%{public}s,messageType:%{public}d",webTag, webMessage->getType(message));size_t len = 0;void *back = webMessage->getData(message, &len);if (webMessage->getType(message) == ArkWeb_WebMessageType::ARKWEB_STRING) {OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb","Native Development Kit WebMessagePortCallback message:%{public}s,messageSize:%{public}d", back, len);} else if (webMessage->getType(message) == ArkWeb_WebMessageType::ARKWEB_BUFFER) {OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb","Native Development Kit WebMessagePortCallback messageSize:%{public}d", len);}}static napi_value NativeWebInit(napi_env env, napi_callback_info info){OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "Native Development Kit NativeWebInit start");size_t argc = 1;napi_value args[1] = {nullptr};napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);// 获取第一个参数webTagsize_t webTagSize = 0;napi_get_value_string_utf8(env, args[0], nullptr, 0, &webTagSize);char *webTagValue = new (std::nothrow) char[webTagSize + 1];size_t webTagLength = 0;napi_get_value_string_utf8(env, args[0], webTagValue, webTagSize + 1, &webTagLength);OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "ArkWeb","Native Development Kit NativeWebInit webTag:%{public}s", webTagValue);controller = reinterpret_cast<ArkWeb_ControllerAPI *>(OH_ArkWeb_GetNativeAPI(ARKWEB_NATIVE_CONTROLLER));if (controller)OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "ArkWeb", "get ArkWeb_ControllerAPI success");webMessagePort =reinterpret_cast<ArkWeb_WebMessagePortAPI *>(OH_ArkWeb_GetNativeAPI(ARKWEB_NATIVE_WEB_MESSAGE_PORT));if (webMessagePort)OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "ArkWeb", "get ArkWeb_WebMessagePortAPI success");webMessage = reinterpret_cast<ArkWeb_WebMessageAPI *>(OH_ArkWeb_GetNativeAPI(ARKWEB_NATIVE_WEB_MESSAGE));if (webMessage)OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "ArkWeb", "get ArkWeb_WebMessageAPI success");OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "Native Development Kit NativeWebInit end");delete[] webTagValue;return nullptr;}static napi_value createWebMessagePorts(napi_env env, napi_callback_info info){size_t argc = 2;napi_value args[2] = {nullptr};napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);// 获取第一个参数webTagsize_t webTagSize = 0;napi_get_value_string_utf8(env, args[0], nullptr, 0, &webTagSize);char *webTagValue = new (std::nothrow) char[webTagSize + 1];size_t webTagLength = 0;napi_get_value_string_utf8(env, args[0], webTagValue, webTagSize + 1, &webTagLength);OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb","Native Development Kit Refresh webTag:%{public}s", webTagValue);// 初始化端口OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "Native Development Kit createWebMessagePorts begin");g_web_message_port_arr = controller->createWebMessagePorts(webTagValue, &g_webMessagePortSize);// 把其中一个端口发送给HTMLArkWeb_ErrorCode code =controller->postWebMessage(webTagValue, "init_web_messageport", g_web_message_port_arr, 1, "*");OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb","Native Development Kit postWebMessage ArkWeb_ErrorCode:%{public}d", code);OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb","Native Development Kit createWebMessagePorts end, web message port size:%{public}d", g_webMessagePortSize);delete[] webTagValue;return nullptr;}static napi_value postMessage(napi_env env, napi_callback_info info){size_t argc = 2;napi_value args[2] = {nullptr};napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);// 获取第一个参数webTagsize_t webTagSize = 0;napi_get_value_string_utf8(env, args[0], nullptr, 0, &webTagSize);char *webTagValue = new (std::nothrow) char[webTagSize + 1];size_t webTagLength = 0;napi_get_value_string_utf8(env, args[0], webTagValue, webTagSize + 1, &webTagLength);OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb","Native Development Kit Refresh webTag:%{public}s", webTagValue);// 发送消息OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "Native Development Kit postMessage begin");if (g_web_message_port_arr == nullptr) {OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "ArkWeb", "webMessagePort is nullptr");return nullptr;}ArkWeb_WebMessagePtr message = webMessage->createWebMessage();webMessage->setType(message, ArkWeb_WebMessageType::ARKWEB_STRING);std::string str = "send string from native";webMessage->setData(message, (void *)str.c_str(), str.length() + 1);ArkWeb_ErrorCode code = webMessagePort->postMessage(g_web_message_port_arr[1], webTagValue, message);OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb","Native Development Kit postMessage ArkWeb_ErrorCode:%{public}d", code);webMessage->destroyWebMessage(&message);OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb","Native Development Kit postMessage end, web message port size:%{public}d", g_webMessagePortSize);delete[] webTagValue;return nullptr;}// 在线程中发消息void sendMessage(const char *webTag, const ArkWeb_WebMessagePtr message){// 发送1000次for (int i = 0; i < 1000; i++) {OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "sendMessage in thread %{public}d", i);if (g_web_message_port_arr && webTag && message) {webMessagePort->postMessage(g_web_message_port_arr[1], webTag, message);}}}static napi_value postMessageThread(napi_env env, napi_callback_info info){size_t argc = 2;napi_value args[2] = {nullptr};napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);// 获取第一个参数webTagsize_t webTagSize = 0;napi_get_value_string_utf8(env, args[0], nullptr, 0, &webTagSize);char *webTagValue = new (std::nothrow) char[webTagSize + 1];size_t webTagLength = 0;napi_get_value_string_utf8(env, args[0], webTagValue, webTagSize + 1, &webTagLength);OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb","Native Development Kit Refresh webTag:%{public}s", webTagValue);// 构造消息OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "Native Development Kit postMessage begin");if (g_web_message_port_arr == nullptr) {OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "ArkWeb", "webMessagePort is nullptr");return nullptr;}ArkWeb_WebMessagePtr message = webMessage->createWebMessage();webMessage->setType(message, ArkWeb_WebMessageType::ARKWEB_STRING);std::string str = "thread message";webMessage->setData(message, (void *)str.c_str(), str.length() + 1);const int numThreads = 5;std::thread threads[numThreads];// 创建线程for (int i = 0; i < numThreads; ++i) {threads[i] = std::thread(sendMessage, webTagValue, message);}// 等待所有线程完成for (int i = 0; i < numThreads; ++i) {threads[i].join();}delete[] webTagValue;return nullptr;}// 在线程中注册回调void SetHandler(const char *webTag){OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "setMessageEventHandler in thread");webMessagePort->setMessageEventHandler(g_web_message_port_arr[1], webTag, WebMessagePortCallback, NULL);}static napi_value setMessageEventHandlerThread(napi_env env, napi_callback_info info){size_t argc = 2;napi_value args[2] = {nullptr};napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);// 获取第一个参数webTagsize_t webTagSize = 0;napi_get_value_string_utf8(env, args[0], nullptr, 0, &webTagSize);char *webTagValue = new (std::nothrow) char[webTagSize + 1];size_t webTagLength = 0;napi_get_value_string_utf8(env, args[0], webTagValue, webTagSize + 1, &webTagLength);OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb","Native Development Kit Refresh webTag:%{public}s", webTagValue);// 注册回调OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb","Native Development Kit SetMessageEventHandler begin");if (g_web_message_port_arr == nullptr) {OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "ArkWeb", "webMessagePort is nullptr");return nullptr;}std::thread thread(SetHandler, webTagValue);thread.detach();webMessagePort->setMessageEventHandler(g_web_message_port_arr[1], webTagValue, WebMessagePortCallback, NULL);OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb","Native Development Kit SetMessageEventHandler end, web message port size:%{public}d", g_webMessagePortSize);delete[] webTagValue;return nullptr;}static napi_value postNoneMessage(napi_env env, napi_callback_info info){size_t argc = 2;napi_value args[2] = {nullptr};napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);// 获取第一个参数webTagsize_t webTagSize = 0;napi_get_value_string_utf8(env, args[0], nullptr, 0, &webTagSize);char *webTagValue = new (std::nothrow) char[webTagSize + 1];size_t webTagLength = 0;napi_get_value_string_utf8(env, args[0], webTagValue, webTagSize + 1, &webTagLength);OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN,"ArkWeb", "Native Development Kit Refresh webTag:%{public}s", webTagValue);// 发送消息OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "Native Development Kit 发消息开始");if (g_web_message_port_arr == nullptr) {OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "ArkWeb", "webMessagePort is nullptr");return nullptr;}ArkWeb_WebMessagePtr message = webMessage->createWebMessage();webMessage->setType(message, ArkWeb_WebMessageType::ARKWEB_NONE);std::string str = "send string from native";webMessage->setData(message, (void *)str.c_str(), str.length() + 1);webMessagePort->postMessage(g_web_message_port_arr[1], webTagValue, message);webMessage->destroyWebMessage(&message);OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb","Native Development Kit postMessage end, web message port size:%{public}d", g_webMessagePortSize);delete[] webTagValue;return nullptr;}static napi_value postBufferMessage(napi_env env, napi_callback_info info){size_t argc = 2;napi_value args[2] = {nullptr};napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);// 获取第一个参数webTagsize_t webTagSize = 0;napi_get_value_string_utf8(env, args[0], nullptr, 0, &webTagSize);char *webTagValue = new (std::nothrow) char[webTagSize + 1];size_t webTagLength = 0;napi_get_value_string_utf8(env, args[0], webTagValue, webTagSize + 1, &webTagLength);OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb","Native Development Kit Refresh webTag:%{public}s", webTagValue);// 发送消息OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "Native Development Kit postMessage begin");if (g_web_message_port_arr == nullptr) {OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "ArkWeb", "webMessagePort is nullptr");return nullptr;}ArkWeb_WebMessagePtr message1 = webMessage->createWebMessage();webMessage->setType(message1, ArkWeb_WebMessageType::ARKWEB_BUFFER);std::string str1 = "send buffer from native";webMessage->setData(message1, (void *)str1.c_str(), str1.length()+1);webMessagePort->postMessage(g_web_message_port_arr[1], webTagValue, message1);webMessage->destroyWebMessage(&message1);OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb","Native Development Kit postMessage end, web message port size:%{public}d", g_webMessagePortSize);delete[] webTagValue;return nullptr;}static napi_value setMessageEventHandler(napi_env env, napi_callback_info info){size_t argc = 2;napi_value args[2] = {nullptr};napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);// 获取第一个参数webTagsize_t webTagSize = 0;napi_get_value_string_utf8(env, args[0], nullptr, 0, &webTagSize);char *webTagValue = new (std::nothrow) char[webTagSize + 1];size_t webTagLength = 0;napi_get_value_string_utf8(env, args[0], webTagValue, webTagSize + 1, &webTagLength);OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb","Native Development Kit Refresh webTag:%{public}s", webTagValue);// 注册回调OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "Native Development Kit SetMessageEventHandler begin");if (g_web_message_port_arr == nullptr) {OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "ArkWeb", "webMessagePort is nullptr");return nullptr;}webMessagePort->setMessageEventHandler(g_web_message_port_arr[1], webTagValue, WebMessagePortCallback, NULL);OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb","Native Development Kit SetMessageEventHandler end, web message port size:%{public}d", g_webMessagePortSize);delete[] webTagValue;return nullptr;}static napi_value closeMessagePort(napi_env env, napi_callback_info info){size_t argc = 2;napi_value args[2] = {nullptr};napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);// 获取第一个参数webTagsize_t webTagSize = 0;napi_get_value_string_utf8(env, args[0], nullptr, 0, &webTagSize);char *webTagValue = new (std::nothrow) char[webTagSize + 1];size_t webTagLength = 0;napi_get_value_string_utf8(env, args[0], webTagValue, webTagSize + 1, &webTagLength);OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb","Native Development Kit Refresh webTag:%{public}s", webTagValue);// 关闭端口,先调用close,再调用destroyWebMessagePortsOH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "Native Development Kit SetMessageEventHandler begin");if (g_web_message_port_arr == nullptr) {OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "ArkWeb", "webMessagePort is nullptr");return nullptr;}webMessagePort->close(g_web_message_port_arr[0], webTagValue);OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb","Native Development Kit SetMessageEventHandler end, web message port size:%{public}d", g_webMessagePortSize);controller->refresh(webTagValue);delete[] webTagValue;return nullptr;}static napi_value destroyMessagePort(napi_env env, napi_callback_info info){size_t argc = 2;napi_value args[2] = {nullptr};napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);// 获取第一个参数webTagsize_t webTagSize = 0;napi_get_value_string_utf8(env, args[0], nullptr, 0, &webTagSize);char *webTagValue = new (std::nothrow) char[webTagSize + 1];size_t webTagLength = 0;napi_get_value_string_utf8(env, args[0], webTagValue, webTagSize + 1, &webTagLength);OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb","Native Development Kit Refresh webTag:%{public}s", webTagValue);// 释放内存,先调用close,再调用destroyWebMessagePortsOH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "Native Development Kit SetMessageEventHandler begin");if (g_web_message_port_arr == nullptr) {OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "ArkWeb", "webMessagePort is nullptr");return nullptr;}controller->destroyWebMessagePorts(&g_web_message_port_arr, g_webMessagePortSize);OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb","Native Development Kit SetMessageEventHandler end, web message port size:%{public}d", g_webMessagePortSize);delete[] webTagValue;return nullptr;}static napi_value destroyNullMessagePort(napi_env env, napi_callback_info info){size_t argc = 2;napi_value args[2] = {nullptr};napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);// 获取第一个参数webTagsize_t webTagSize = 0;napi_get_value_string_utf8(env, args[0], nullptr, 0, &webTagSize);char *webTagValue = new (std::nothrow) char[webTagSize + 1];size_t webTagLength = 0;napi_get_value_string_utf8(env, args[0], webTagValue, webTagSize + 1, &webTagLength);OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb","Native Development Kit Refresh webTag:%{public}s", webTagValue);// 释放内存,先调用close,再调用destroyWebMessagePortsOH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb", "Native Development Kit SetMessageEventHandler begin");controller->destroyWebMessagePorts(&g_web_message_port_arr, g_webMessagePortSize);OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "ArkWeb","Native Development Kit SetMessageEventHandler end, web message port size:%{public}d", g_webMessagePortSize);delete[] webTagValue;return nullptr;}EXTERN_C_STARTstatic napi_value Init(napi_env env, napi_value exports){napi_property_descriptor desc[] = {{"nativeWebInit", nullptr, NativeWebInit, nullptr, nullptr, nullptr, napi_default, nullptr},{"createWebMessagePorts", nullptr, createWebMessagePorts, nullptr, nullptr, nullptr, napi_default, nullptr},{"postMessage", nullptr, postMessage, nullptr, nullptr, nullptr, napi_default, nullptr},{"postNoneMessage", nullptr, postNoneMessage, nullptr, nullptr, nullptr, napi_default, nullptr},{"postBufferMessage", nullptr, postBufferMessage, nullptr, nullptr, nullptr, napi_default, nullptr},{"setMessageEventHandler", nullptr, setMessageEventHandler, nullptr, nullptr, nullptr, napi_default, nullptr},{"closeMessagePort", nullptr, closeMessagePort, nullptr, nullptr, nullptr, napi_default, nullptr},{"destroyMessagePort", nullptr, destroyMessagePort, nullptr, nullptr, nullptr, napi_default, nullptr},{"postMessageThread", nullptr, postMessageThread, nullptr, nullptr, nullptr, napi_default, nullptr},{"setMessageEventHandlerThread", nullptr, setMessageEventHandlerThread, nullptr, nullptr, nullptr,napi_default, nullptr},{"destroyNullMessagePort", nullptr, destroyNullMessagePort, nullptr, nullptr, nullptr, napi_default, nullptr},};napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);return exports;}EXTERN_C_ENDstatic napi_module demoModule = {.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(&demoModule); }