使用Node-API进行同步任务开发

2024-09-07 11:12

本文主要是介绍使用Node-API进行同步任务开发,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

        在同步任务开发中,ArkTS应用侧主线程将阻塞等待Native侧计算结果,Native侧计算结果通过方舟引擎反馈给ArkTS应用侧。此过程中,Native接口代码与ArkTS应用侧均运行在ArkTS主线程上。为了Native侧业务处理具有同步效果,案例中的生产者与消费者线程则采用join()的方式来进行同步处理。

        同步调用也支持带Callback,具体方式由应用开发者决定,通过是否传递Callback函数进行区分。

        从上图中,可以看出,当Native同步任务接口被调用时,该接口会完成参数解析、数据类型转换、创建生产者和消费者线程等。在等待生产者线程和消费者线程执行结束后,将图片路径结果转换为napi_value,由方舟引擎直接反馈到ArkTS应用侧。

一、同步任务开发步骤(简介)       

        1、ArkTS应用侧开发

// Index.ets文件// 导入libentry.so库,返回ArkTS对象testNapi 
import testNapi from 'libentry.so';
import Constants from '../../common/constants/CommonConstants';@Entry
@Component
struct Index {build() {Column() {...Column() {...Button($r('app.string.sync_button_title'))....onClick(() => {// 通过testNapi,传入callback回调,调用Native接口,进行业务计算testNapi.addSyncCallback(2,3,(nativeResult: number) => {this.result = nativeResult;})...}...}...}
}

        2、Native侧开发 

// index.d.ts文件// ArkTS侧的Native接口声明
export const addSyncCallback: (a: number, b: number,callback: (nativeResult: number) => void) => void;
static napi_value AddSyncCallback(napi_env env,napi_callback_info info) {...// 解析ArkTS应用侧传入参数napi_get_cb_info(env, info, &argc, args, &context, nullptr);// 将参数从napi_value类型转换为double类型double value0;napi_get_value_double(env, args[0], &value0);double value1;napi_get_value_double(env, args[1], &value1);napi_value callBackArg = nullptr;// 业务处理,两数相加,将结果返回napi_valuenapi_create_double(env, add(value0, value1), &callBackArg);napi_value res = nullptr;// 通过回调返回结果到应用napi_call_function(env, context, args[2], 1, callBackArg, &res);return res;
}

二、同步任务开发步骤(实例)

        1、ArkTS应用侧开发

import testNapi from 'libentry.so';
import Constants from '../../common/constants/CommonConstants';@Entry
@Component
struct Index {@State imagePath: string = Constants.INIT_IMAGE_PATH;imageName: string = '';build() {Column() {...// button list, prompting the user to click the button to select the target image.Column() {...// multi-threads sync call buttonButton($r('app.string.sync_button_title')).width(Constants.FULL_PARENT).margin($r('app.float.button_common_margin')).onClick(() => {this.imageName = Constants.SYNC_BUTTON_IMAGE;this.imagePath = Constants.IMAGE_ROOT_PATH + testNapi.getImagePathSync(this.imageName);})...}...}...}
}

        2、Native侧开发

        在同步任务开发中,Native侧接口原生代码仍然运行在ArkTS主线程上。

        导出Native接口:将Native接口导出到ArkTS侧,用于支撑ArkTS对象调用和模块编译构建。

// export sync interface
export const getImagePathSync: (imageName: string) => string;

        上下文数据结构定义:用于任务执行过程中,上下文数据存储。后文异步任务开发和线程安全开发中实现相同,后续不再赘述。

// context data provided by users
// data is transferred between the native method (initialization data), ExecuteFunc, and CompleteFunc
struct ContextData {napi_async_work asyncWork = nullptr; // async work objectnapi_deferred deferred = nullptr;    // associated object of the delay object promisenapi_ref callbackRef = nullptr;      // reference of callbackstring args = "";                    // parameters from ArkTS --- imageNamestring result = "";                  // C++ sub-thread calculation result --- imagePath
};

        销毁上下文数据:在任务执行结束或者失败后,需要销毁上下文数据进行内存释放。后文异步任务开发和线程安全开发中实现相同,后续不再赘述。

// MultiThreads.cpp文件static void DeleteContext(napi_env env, ContextData *contextData) {// delete callback referenceif (contextData->callbackRef != nullptr) {(void)napi_delete_reference(env, contextData->callbackRef);}// delete async workif (contextData->asyncWork != nullptr) {(void)napi_delete_async_work(env, contextData->asyncWork);}// release context datadelete contextData;
}

        Native同步任务开发接口:解析ArkTS应用侧参数、数据类型转换、创建生产者和消费者线程,并使用join()进行同步处理。最后在获取结果后,将数据转换为napi_value类型,返回给ArkTS应用侧。

// MultiThreads.cpp文件
// sync interface
static napi_value GetImagePathSync(napi_env env, napi_callback_info info) {size_t paraNum = 1;napi_value paraArray[1] = {nullptr};// parse parametersnapi_status operStatus = napi_get_cb_info(env, info, &paraNum, paraArray, nullptr, nullptr);if (operStatus != napi_ok) {return nullptr;}napi_valuetype paraDataType = napi_undefined;operStatus = napi_typeof(env, paraArray[0], &paraDataType);if ((operStatus != napi_ok) || (paraDataType != napi_string)) {return nullptr;}// convert napi_value to char *constexpr size_t buffSize = 100;char strBuff[buffSize]{}; // char buffer for imageName stringsize_t strLength = 0;operStatus = napi_get_value_string_utf8(env, paraArray[0], strBuff, buffSize, &strLength);if ((operStatus != napi_ok) || (strLength == 0)) {return nullptr;}// defines context data. the memory will be released in CompleteFuncauto contextData = new ContextData;contextData->args = strBuff;// create producer threadthread producer(ProductElement, static_cast<void *>(contextData));producer.join();// create consumer threadthread consumer(ConsumeElement, static_cast<void *>(contextData));consumer.join();// convert the result to napi_value and send it to ArkTs applicationnapi_value result = nullptr;(void)napi_create_string_utf8(env, contextData->result.c_str(), contextData->result.length(), &result);// delete context dataDeleteContext(env, contextData);return result;
}

这篇关于使用Node-API进行同步任务开发的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1144899

相关文章

Linux使用fdisk进行磁盘的相关操作

《Linux使用fdisk进行磁盘的相关操作》fdisk命令是Linux中用于管理磁盘分区的强大文本实用程序,这篇文章主要为大家详细介绍了如何使用fdisk进行磁盘的相关操作,需要的可以了解下... 目录简介基本语法示例用法列出所有分区查看指定磁盘的区分管理指定的磁盘进入交互式模式创建一个新的分区删除一个存

C#使用HttpClient进行Post请求出现超时问题的解决及优化

《C#使用HttpClient进行Post请求出现超时问题的解决及优化》最近我的控制台程序发现有时候总是出现请求超时等问题,通常好几分钟最多只有3-4个请求,在使用apipost发现并发10个5分钟也... 目录优化结论单例HttpClient连接池耗尽和并发并发异步最终优化后优化结论我直接上优化结论吧,

SpringBoot使用Apache Tika检测敏感信息

《SpringBoot使用ApacheTika检测敏感信息》ApacheTika是一个功能强大的内容分析工具,它能够从多种文件格式中提取文本、元数据以及其他结构化信息,下面我们来看看如何使用Ap... 目录Tika 主要特性1. 多格式支持2. 自动文件类型检测3. 文本和元数据提取4. 支持 OCR(光学

JAVA系统中Spring Boot应用程序的配置文件application.yml使用详解

《JAVA系统中SpringBoot应用程序的配置文件application.yml使用详解》:本文主要介绍JAVA系统中SpringBoot应用程序的配置文件application.yml的... 目录文件路径文件内容解释1. Server 配置2. Spring 配置3. Logging 配置4. Ma

Linux使用dd命令来复制和转换数据的操作方法

《Linux使用dd命令来复制和转换数据的操作方法》Linux中的dd命令是一个功能强大的数据复制和转换实用程序,它以较低级别运行,通常用于创建可启动的USB驱动器、克隆磁盘和生成随机数据等任务,本文... 目录简介功能和能力语法常用选项示例用法基础用法创建可启动www.chinasem.cn的 USB 驱动

基于Python开发电脑定时关机工具

《基于Python开发电脑定时关机工具》这篇文章主要为大家详细介绍了如何基于Python开发一个电脑定时关机工具,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 简介2. 运行效果3. 相关源码1. 简介这个程序就像一个“忠实的管家”,帮你按时关掉电脑,而且全程不需要你多做

C#使用yield关键字实现提升迭代性能与效率

《C#使用yield关键字实现提升迭代性能与效率》yield关键字在C#中简化了数据迭代的方式,实现了按需生成数据,自动维护迭代状态,本文主要来聊聊如何使用yield关键字实现提升迭代性能与效率,感兴... 目录前言传统迭代和yield迭代方式对比yield延迟加载按需获取数据yield break显式示迭

使用SQL语言查询多个Excel表格的操作方法

《使用SQL语言查询多个Excel表格的操作方法》本文介绍了如何使用SQL语言查询多个Excel表格,通过将所有Excel表格放入一个.xlsx文件中,并使用pandas和pandasql库进行读取和... 目录如何用SQL语言查询多个Excel表格如何使用sql查询excel内容1. 简介2. 实现思路3

java脚本使用不同版本jdk的说明介绍

《java脚本使用不同版本jdk的说明介绍》本文介绍了在Java中执行JavaScript脚本的几种方式,包括使用ScriptEngine、Nashorn和GraalVM,ScriptEngine适用... 目录Java脚本使用不同版本jdk的说明1.使用ScriptEngine执行javascript2.

c# checked和unchecked关键字的使用

《c#checked和unchecked关键字的使用》C#中的checked关键字用于启用整数运算的溢出检查,可以捕获并抛出System.OverflowException异常,而unchecked... 目录在 C# 中,checked 关键字用于启用整数运算的溢出检查。默认情况下,C# 的整数运算不会自