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

相关文章

Python并行处理实战之如何使用ProcessPoolExecutor加速计算

《Python并行处理实战之如何使用ProcessPoolExecutor加速计算》Python提供了多种并行处理的方式,其中concurrent.futures模块的ProcessPoolExecu... 目录简介完整代码示例代码解释1. 导入必要的模块2. 定义处理函数3. 主函数4. 生成数字列表5.

Python中help()和dir()函数的使用

《Python中help()和dir()函数的使用》我们经常需要查看某个对象(如模块、类、函数等)的属性和方法,Python提供了两个内置函数help()和dir(),它们可以帮助我们快速了解代... 目录1. 引言2. help() 函数2.1 作用2.2 使用方法2.3 示例(1) 查看内置函数的帮助(

Linux脚本(shell)的使用方式

《Linux脚本(shell)的使用方式》:本文主要介绍Linux脚本(shell)的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录概述语法详解数学运算表达式Shell变量变量分类环境变量Shell内部变量自定义变量:定义、赋值自定义变量:引用、修改、删

Python实例题之pygame开发打飞机游戏实例代码

《Python实例题之pygame开发打飞机游戏实例代码》对于python的学习者,能够写出一个飞机大战的程序代码,是不是感觉到非常的开心,:本文主要介绍Python实例题之pygame开发打飞机... 目录题目pygame-aircraft-game使用 Pygame 开发的打飞机游戏脚本代码解释初始化部

Java使用HttpClient实现图片下载与本地保存功能

《Java使用HttpClient实现图片下载与本地保存功能》在当今数字化时代,网络资源的获取与处理已成为软件开发中的常见需求,其中,图片作为网络上最常见的资源之一,其下载与保存功能在许多应用场景中都... 目录引言一、Apache HttpClient简介二、技术栈与环境准备三、实现图片下载与保存功能1.

Python中使用uv创建环境及原理举例详解

《Python中使用uv创建环境及原理举例详解》uv是Astral团队开发的高性能Python工具,整合包管理、虚拟环境、Python版本控制等功能,:本文主要介绍Python中使用uv创建环境及... 目录一、uv工具简介核心特点:二、安装uv1. 通过pip安装2. 通过脚本安装验证安装:配置镜像源(可

LiteFlow轻量级工作流引擎使用示例详解

《LiteFlow轻量级工作流引擎使用示例详解》:本文主要介绍LiteFlow是一个灵活、简洁且轻量的工作流引擎,适合用于中小型项目和微服务架构中的流程编排,本文给大家介绍LiteFlow轻量级工... 目录1. LiteFlow 主要特点2. 工作流定义方式3. LiteFlow 流程示例4. LiteF

使用Python开发一个现代化屏幕取色器

《使用Python开发一个现代化屏幕取色器》在UI设计、网页开发等场景中,颜色拾取是高频需求,:本文主要介绍如何使用Python开发一个现代化屏幕取色器,有需要的小伙伴可以参考一下... 目录一、项目概述二、核心功能解析2.1 实时颜色追踪2.2 智能颜色显示三、效果展示四、实现步骤详解4.1 环境配置4.

canal实现mysql数据同步的详细过程

《canal实现mysql数据同步的详细过程》:本文主要介绍canal实现mysql数据同步的详细过程,本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的... 目录1、canal下载2、mysql同步用户创建和授权3、canal admin安装和启动4、canal

使用jenv工具管理多个JDK版本的方法步骤

《使用jenv工具管理多个JDK版本的方法步骤》jenv是一个开源的Java环境管理工具,旨在帮助开发者在同一台机器上轻松管理和切换多个Java版本,:本文主要介绍使用jenv工具管理多个JD... 目录一、jenv到底是干啥的?二、jenv的核心功能(一)管理多个Java版本(二)支持插件扩展(三)环境隔