鸿蒙如何在Native调用ArkTS方法

作者: Mike98

责任编辑: 耿立影

来源: 专栏

时间: 2025-11-21 15:03

关键字: 鸿蒙 ArkTS

浏览: 2317

点赞: 128

收藏: 11

鸿蒙作为一款新兴的智能操作系统,现在适配鸿蒙系统的应用越来越多,同时会面临三端兼容问题,如同一产品功能,需要维护iOS、Android、鸿蒙三端代码。

拿文件上传、下载功能场景举例,同时要适配iOS、Android、鸿蒙三端,目前比较好的方案是文件上传、下载功能下沉到C,三端native代码可以复用,但是在鸿蒙上存在如下一个问题:

Native文件上传、下载进度怎么从Native线程异步回调给ArkTs线程对应JS回调方法?

答案:通过Node-API提供的线程安全函数,可以把文件上传、下载进度从native线程异步回调ArkTs线程JS回调方法。

Node-API(以前称为 N-API)是用于构建native功能的API,它独立于底层的JavaScript引擎(例如 V8引擎),并作为 Node.js 本身的一部分进行维护。

Node.js是JavaScript运行时环境,用来支持JS代码的执行,HarmonyOS Native API对Node-API的接口进行了封装和重写,支持Node-API标准款的部分接口,以此提供ArkTS/JS与C/C++模块之间交互能力。

Node-API必须遵循一个原则: Node-API的调用必须和JS的调用线程一致。

1)Node-API接口只能在JS线程使用,JS调用Native的线程才能调用Node-API接口,Native子线程无法调用;

2)napi env是无法跨线程使用,如果使用全局变量将napi env保存下来,再在其他线程使用会崩溃。

上面提到的文件上传场景,文件上传是在native子线程,非JS线程,如果使用Node-API,必然会崩溃,但Node-API提供线程安全函数,通过线程安全函数可以在native线程里回调JS线程。

3.1 线程安全函数

线程安全函数ThreadSafeFunction(简称TFS)为了解决跨线程的函数调用问题,可以将普通的JS函数封装成线程安全函数,包装之后的函数是允许在线程之间传递,线程安全函数的定义

使用TFS一般分为如下几步:step1:native侧创建线程安全函数,绑定ArkTs的API的callback和线程安全回调函数call\_js\_cb;

step2:native子线程执行异步任务,并在子线程中调用napi_call_threadsafe_function,将call_js_cb抛到事件循环中进行调度;

step3:在call_js_cb中通过调用napi_call_function将native异步任务的结果回调给ArkTs线程,进行相关的UI刷新操作。

3.2 EventLoop事件循环

Libuv是由C语言编写的,基于事件驱动的异步I/O库,利用编译好的libuv库文件,可以写一个简单事件驱动的例子:

线程安全函数是怎么实现主线程、线程之间通信?

libuv通过循环不断取出watcher队列中的事件,uv__iot_t结构体保存了文件描述符,其对应一个事件和事件回调,通过uv__iot_t结构体来初始化 epoll_event,再使用epoll_wait来等待文件描述符上I/O事件,事件触发之后调用对应的回调函数,通过epoll实现线程间的通信。


API解释
uv_run(uv_loop_t* loop, uv_run_mode mode)运行事件循环,有如下几种mode:UV_RUN_DEFAULT:运行事件循环直到没有更多的活动的和被引用到的句柄或请求UV_RUN_ONCE:轮询I/O一次 UV_RUN_NOWAIT:轮询I/O一次但不会阻塞,如若没有待处理的回调函数时
uv_loop_alive(const uv_loop_t* loop)如果有被引用的活动句柄、活动请求或者循环里的关闭句柄时返回非零值,否则返回零值,表示事件不再活动
uv__io_tIO观察者,是一个结构体,描述了上层事件和事件回调信息
uv__io_poll(loop, timeout)把新增需要被监听的fd放到poll中,其内部有一个epoll_wait方法
uv_async_start、uv__io_start注册IO观察者到事件loop里,并注册需要监听的事件
uv__async_send、uv_async_send触发事件执行,并执行事件的回调

在Native侧调用ArkTS侧的系统能力,除了使用线程安全函数外,还可以直接使用libuv,但需要额外编译libuv源码,如果需要了解更多libuv的知识,可以参见(https://github.com/libuv/libuv)。

©本站发布的所有内容,包括但不限于文字、图片、音频、视频、图表、标志、标识、广告、商标、商号、域名、软件、程序等,除特别标明外,均来源于网络或用户投稿,版权归原作者或原出处所有。我们致力于保护原作者版权,若涉及版权问题,请及时联系我们进行处理。