当前位置: 首页 > news >正文

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


http://www.mrgr.cn/news/21363.html

相关文章:

  • 【JavaEE初阶】多线程(2)
  • 使用Node-API进行异步任务开发
  • 执行任务赚积分
  • 成功的原则
  • Spring MVC 执行流程详解
  • 最优化方法Python计算:求解约束优化问题的拉格朗日乘子算法
  • python图像处理的图像几何变换
  • HivisionIDPhoto V2 - AI一键智能制作生成证件照 新增抠图模型,优化抠图效果 本地一键整合包下载
  • Java面试篇基础部分-JVM内存运行时机制
  • [羊城杯 2021]Ez_android-快坚持不下去的第五天
  • 多云架构下大模型训练的存储稳定性探索
  • 音视频开发之旅(92)-多模态Clip论文解读与源码分析
  • exit与_exit详解,并于进程间的关系
  • 实例讲解Simulink油门踏板信号解析及故障判定模型搭建方法
  • Docker 容器技术:简化 MySQL 主从复制部署与优化
  • 久久派简单搭建小游戏网站
  • ABB机器人无限解包( rawbytes)
  • Pytorch多GPU分布式训练代码编写
  • box64 安装
  • 2024 年高教社杯全国大学生数学建模竞赛B题第三问详细解题思路(终版)