HarmonyOS:Node-API典型场景开发(1)
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤博客园地址:为敢技术(https://www.cnblogs.com/strengthen/ )
➤GitHub地址:https://github.com/strengthen
➤原文地址:https://www.cnblogs.com/strengthen/p/18504101
➤如果链接不是为敢技术的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
3、Callback异步方式交互流程。
(1)、异步方式与同步方式的区别在于,同步方式中所有代码的处理都在ArkTS主线程中完成,而异步方式中的所有代码在多线程中完成。
(2)、Node-API异步接口实现支持Callback方式和Promise方式,具体使用哪种方式由应用开发者决定,通过是否传递callback函数进行区分。
callback模式下的异步任务是怎样进行交互的:ArkTS应用侧调用运行在主线程上的Native接口,在Native接口中,通过使用相应的API进行参数解析,创建callback引用置入上下文,创建异步工作项,并将任务置入队列,等待系统调度给应用侧返回临时空值,避免阻塞应用侧。当work子线程被调度后,将会执行execute回调,执行异步业务逻辑,并将计算结果写入上下文。在EventLoop子线程中,当事件被调度将会执行complete回调。在complete回调中,将会解析上下文,通过napi_get_reference_value解引用获取callback,最后通过napi_call_function接口触发回调。将异步结果返回到应用侧刷新UI界面。
4、Promise异步方式交互流程。
(1)、Promise异步模型时序交互流程与callback异步模型基本一致。具体差异在于promise方式不需要callback层层回调,而是通过对象解析的方式进行数据反馈。
(2)、promise模型下Native接口会创建promise对象返回给应用侧而非临时空值。Promise模型下,complete回调将会通过napi_resolve_deferred 接口,解析异步结果到应用侧而非触发回调。
5、异步任务的开发实现-callback异步方法。
(1)、ArkTS应用侧开发:首先导入包含Native业务逻辑的动态库,并返回一个ArkTS对象testNapi,然后通过testNapi对象调用Native接口传入callback回调进行业务计算。
(2)、导出Native接口:声明一个ArkTS接口用以映射Native侧C++接口,并用export进行导出。
(3)、Execute回调实现:主要执行业务逻辑,也就是将两数相加并将结果置入上下文。
(4)、Complete回调实现:将会执行解析上下文数据,将callback解引用,结果类型转换,然后通过napi_call_function触发callback回调,将结果返回到ArkTS应用侧,最后还需要销毁上下文数据,释放内存。
(5)、Native接口实现:将主要实现解析ArkTS侧传入的参数,将参数类型从napi_value转换为double,分配上下文内存空间,将参数写入上下文。然后给应用侧传入的callback回调创建引用,创建异步工作项,注册绑定execute和complete两个回调,将异步任务入队,等待系统调度,最后返回临时空值到应用避免阻塞应用侧。
5、线程安全机制等原理:Node-API提供了类型napithreadsafe_function(线程安全函数)以及创建、销毁和调用该类型对象的API来完成线程安全开发。
(1)、定义线程安全回调,用以反馈结果到应用侧。
(2)、定义C++子线程执行函数,用以执行业务逻辑和调用线程安全函数对象。
(3)、napi_create_threadsafe_function,创建线程安全函数对象,注册绑定回调。
(4)、创建C++子线程,等待系统调度,
(5)、返回临时空值到应用,避免ArkTS侧被阻塞。
(6)、等待调度。
在创建线程安全函数时,
(1)、会通过uv_async_init接口,将处理回调与线程异步通信句柄进行绑定。
(2)、当C++子线程被调度后将执行业务计算。
(3)、同时通过napi_call_threadsafe_function接口。
(4)、将线程安全回调call_js_cb抛到EventLoop事件循环。
(5)、在EventLoop子线程中将会执行call_js_cb回调。
(6)、调用Node-API接口将异步执行结果返回到应用。
6、线程安全的时序交互流程:
(1)、ArkTS应用侧调用运行在主线程上的Native接口。
(2)、在Native接口中通过使用相应的API进行参数解析。
(3)、创建线程安全函数对象。
(4)、创建C++子线程,等待系统调度。
(5)、给应用侧返回临时空值,避免阻塞应用侧。
线程调度:
(1)、当C++子线程被调用将会执行异步业务逻辑,
(2)、并将计算结果写入上下文。
(3)、通过napi_call_threadsafe_function接口
(4)、将call_js_cb回调到事件循环。
当事件被调度,会执行call_js_cb回调:
(1)、解析上下文数据。
(2)、通过napi_call_function接口触发回调。
(3)、将异步结果返回到应用侧,刷新UI界面。
7、线程安全开发实践:
(1)、ArkTS应用侧开发:导入包含Native业务逻辑的动态库,并返回一个ArkTS对象的testNapi。然后通过testNapi对象调用Native接口传入callback回调进行业务计算。
(2)、导出Native接口:声明一个ArkTS接口,用于映射Native侧C++接口并用export进行导出。
(3)、C++子线程执行函数:主要执行业务逻辑,示例代码中也是将两数相加,并将结果置入上下文。同时调用线程安全函数将回调任务抛到EventLoop事件循环中。
(4)、Call_js_cb回调实现:将会执行解析上下文数据,结果类型转换为napi_value,通过napi_call_function触发callback回调,将结果反馈到ArkTS应用侧,最后需要销毁上下文数据释放内存。
(5)、Native接口实现:解析ArkTS侧传入的参数,分配上下文内存空间,将参数写入上下文,创建线程安全函数对象,注册绑定callback和call_js_cb回调。创建C++子线程,等待系统调度,最后返回临时空值到应用,避免阻塞。
参考链接:示例代码