NAPI(Native API)是OpenHarmony系统中的一套原生模块扩展开发框架,它基于Node.js N-API规范开发,为开发者提供了JavaScript与C/C++模块之间相互调用的交互能力。这套机制对于鸿蒙系统开发的价值有两方面:
- 鸿蒙系统可以将框架层丰富的模块功能通过js接口开放给上层应用使用。
- 应用开发者也可以选择将一些对性能、底层系统调用有要求的核心功能用C/C++封装实现,再通过js接口使用,提高应用本身的执行效率。
1. NAPI在系统中的位置
NAPI在OpenHarmony中属于UI框架的一部分。
实现一个NAPI模块,开发者需要完成模块注册、定义接口映射、实现回调方法等工作,这些工作在NAPI框架内部是怎么起作用的,为了实现Js与C++的交互,框架又做了哪些事情?今天我们就来看一看NAPI框架的内部实现。
2. NAPI框架代码目录结构
NAIP框架代码在 foundation\arkui\napi\ 路径下。总体上可分为interface、native_engine 和 xxxManager 三部分。
interface 目录为NAPI开发者提供了各种常用功能的API接口及宏定义。
native_engine 目录是NAPI框架的核心部分,interface目录提供的接口对应的功能都在这里实现。C++与Js之间的调用交互最终是要依托JS引擎来完成的,针对系统支持的不同JS引擎,在impl目录中也有对应的4种实现(ark, jerryscript, quickjs, v8)。
此外,还有几个Manager目录,分别负责模块注册、引用对象管理、作用域管理等专项功能。
我们知道,一个模块被设计成什么样,往往是由它面临的问题决定的。为了了解这些目录的各个组成部分发挥的作用,我们先来看看JS调用C++的过程中,NAPI框架需要解决哪些问题。
3. NAPI框架完成的主要工作
假设我们在框架层用C/C++实现了一个myapp模块,这个模块可以为应用提供系统访问次数的统计。为了让应用层的JS代码能够使用这项能力,我们为应用开发者提供了如下的JS接口:
@ohos.myapp.d.ts
declare namespace myapp {
// 同步方法
function getVisitCountSync(key: string, defaultValue?: string): string;
// 异步方法
function getVisitCountAsync(key: string, callback: AsyncCallback<string>): void; // callback回调方式
function getVisitCountAsync(key: string, defaultValue?: string): Promise<string>; // Promise方式
}
App应用开发者的JS代码简单导入一下模块就可以直接调用了。
import myapp1 from "@ohos.myapp"
var result = myapp1.getVisitCountSync("www.mywebsite.com");
为了实现这样的调用,NAPI框架需要解决以下问题,各个子模块在其中都发挥了相关作用。
1)模块注册(import的模块名称”myapp”,是怎么对应到实际的c++lib库的?) — Module Manager
2)方法名映射(js调用的”getVisitCountSync”等方法,是怎么对应到native的C/C++的方法的?) — Native Engine
3)数据传递与转换(js传入的入参、得到的返回结果,需要转换成C/C++代码可以操作的数据类型)— NativeValue
而对于稍微再复杂一点的异步调用:
/** Promise 方式的异步调用 */
var promiseObj = myapp1.getVisitCountAsync("www.mywebsite.com").then(data => {
......
}).catch(error =>