首页 前端知识 OpenHarmony 入门——初识JS/ArkTS 侧的“JNI” NAPI(一)

OpenHarmony 入门——初识JS/ArkTS 侧的“JNI” NAPI(一)

2024-08-15 22:08:56 前端知识 前端哥 1003 990 我要收藏

引言

在Android中Java可以通过JNI 与C/C++ 通信,而在OpenHarmony 中前段语言目前是ETS,那么OpenHarmony中的 “JNI” 角色是什么呢?

一、NAPI概述

NAPI全称Native Application Programming Interface(最新版的文档已经改为Node-API了)属于UI框架ArkUI子系统的一部分,类似于Java中使用的 JNI机制,OpenHarmorny 中的 NAPI(由Node.js N-API 框架扩展而来) 用于通过 JS/ETS 语言编写的代码与 native 代码(C/C++ )交互。NAPI适合封装IO、CPU密集型、OS底层等能力并对外暴露JS接口,通过NAPI可以实现JS与C/C++代码互相访问。
在这里插入图片描述

  • NativeEngine——JS引擎抽象层,统一JS引擎在NAPI层的接口行为。
  • ModuleManager——管理模块,用于模块加载、模块信息缓存。
  • ScopeManager——管理NativeValue的生命周期。
  • ReferenceManager——管理NativeReference的生命周期。

因为在OpenHarmony中应用层的语言是基于TypeScript的,因此系统默认会提供响应系统能力的JS 接口,目前主要有三种:

  • JSI机制:L0~L1设备支持。
  • Channel机制:L3设备支持。
  • N-API机制:目前仅L2设备支持,后续须推广到L3~L5设备。

二、JavaScript 和TypeScript

TypeScript 是 JavaScript 的类型的超集,支持ES6语法,支持面向对象编程的概念,如类、接口、继承、泛型等,是一种静态类型检查的语言,提供了类型注解,在代码编译阶段就可以检查出数据类型的错误同时扩展了JavaScript 的语法,所以任何现有的JavaScript 程序可以不加改变的在 TypeScript 下工作为了保证兼容性,TypeScript 在编译阶段需要编译器编译成纯 JavaScript 来运行。TypeScript 文件的后缀名 .ts (.ts,.tsx,.d.ts),JavaScript 文件是 .js。

ArkTS 则是在TypeScript 基础上扩展一些功能,增加一些类似语法糖和“注解”作用的

1、.ts 和.d.ts文件

.ts 文件包含实际的代码逻辑,用于编写 TypeScript 程序的实现,文件包含了变量、函数、类等 TypeScript 代码的定义和实现。在编译时.ts 文件将被转换为 JavaScript 文件,从而可以在浏览器或其他 JavaScript 运行环境中执行;而 .d.ts 文件是类型声明文件里面只有类型代码,没有具体的代码实现。它的文件名一般为[模块名].d.ts的形式,其中的d表示 declaration(声明),用于描述 JavaScript 代码在 TypeScript 中的类型信息。 从简而言之,.ts 文件是我们编写实际业务逻辑的地方,而 .d.ts 文件是用于提供类型声明的地方。比如我们有个JS文件 calc.js:

const calc = (x, y)=> x * y;
export {calc}

TypeScript 没有关于函数的任何信息,包括名称、参数类型,为了在 TypeScript 文件中使用该函数,需要在 d.ts 文件中提供其定义:

// calc.d.ts
declare function calc(a: number, b: number): number

然后就可以在 TypeScript 中使用该函数且不会出现任何编译错误。在 TypeScript 中,当我们引入第三方 JavaScript 库时,如果该库没有提供类型定义文件,我们就需要手动编写一个对应的声明文件,以便在编写 TypeScript 代码时能够正确地获得类型提示和类型检查。

declare module yourlibname {
	export function calculate(x: number, y: number): number;
}

2、关于d.ts的注意事项

以下为应用开发者提供了四个的JS接口,分为同步接口与异步接口两类,异步接口又分为回调方式与Promise。

import {AsyncCallback, Callback} from "./basic";
 
declare namespace SendFile {
  // 异步接口----回调方式
  function sendFile(deviceId: string, sourPath: Array<string>, destPath: Array<string>, fileCount: number, callback: AsyncCallback<number>);
  // 异步接口----Promise方式
  function sendFile(deviceId: string, sourPath: Array<string>, destPath: Array<string>, fileCount: number): Promise<number>;
  // 异步接口----回调方式
  function on(type: 'sendFinished' | 'receiveFinished', callback: AsyncCallback<TransResult>): void;
  // 同步接口
  function off(type: 'sendFinished' | 'receiveFinished'): void;
}
 
export default SendFile;

使用时只需要导入相关模块即可

// 同步调用
import myapp1 from "@ohos.SendFile"
var result = myapp1.off(/* 参数自填*/);
 
// 异步调用
/** call back 方式的异步调用 */
myapp1.sendFile("xxxx", sourPath, destPath, 4, function (err, ret) {
    ......
});
/** Promise 方式的异步调用 */
var  promiseObj = myapp1.sendFile("xxxx", sourPath, destPath, 4).then(data => {
    ......
}).catch(error => {
    ......
});
  • 自定义d.ts接口文件时,在应用开发工具(DevEco Studio)里需要将此文件放入Openharmony SDK所在目录中,例如在作者的本机为D:\Program\Huawei\OpenHarmony3.1\Sdk\ets\3.1.5.5\api与D:\Program\Huawei\OpenHarmony3.1\Sdk\js\3.1.5.5\api,根据应用调用者(js或ets)的不同放入不同的目录。
  • Openharmony已有d.ts接口文件,根据文件中注释里说的@since 9对应相应的导入sdk版本后,不需要另做导入d.ts。

OpenHarmony SDK中的部分声明文件存放在\ets\api\bundle下

.d.ts 本身的文件的名称直接关联的是register时的nm_module的值
interface_sdk-js API声明文件库提供了OpenHarmony 所有的JS API接口,进入api文件夹即可看到声明文件。我们要是想自定义自己的JS API接口,需要向ACE 申请一个唯一的module 名,然后注册进来copy到指定的路径下即可,理论上一个@.d.ts文件对应一个so,映射到C++的一个类,在里面注册完成映射。

三、NAPI 基础理论知识

1、基础数据类型

NAPI框架,所有参数,无论是ECMAScript标准中定义的Boolean、Null、Undefined、Number、BigInt、String、Symbol和Object八种数据类型,还是Function类型,都已统一封装为napi_value类型,故可如获取数据类型的参数一样获取Function类型参数。oh 中的具体实现在native_api.cpp其中基本的数据类型

  • napi_env 对应 NativeEngine 在 oh 中指 ArkComplier 中 JSNAPI 的相关上下文环境,任何 napi 数据类型和 js 数据类型的转换都需要用到它。
  • napi_value 对应 NativeValue 在 oh 中指所有 ArkComplier 可识别的 js 数据类型,它有子类 ArkNativeNumber、ArkNativeString、ArkNativeFunction 等,对应 js 中的 number、string、function 等数据类型。
typedef napi_value (*napi_callback)(napi_env env, napi_callback_info info)
  • napi_callback_info 对应 NativeCallbackInfo ,指注册 callback handle 时用来存放 js 传入参数信息的数据类型。它是一个 struct。
  • napi_property_descriptor 是用来存放单个 property 的数据类型。
  • napi_callback 对应 NativeCallback,即前面的 callback handle,native 代码将其注册为对应 js 接口的回调函数。

2、基本的转换函数

  • 将 c++ 转换成 napi 的函数: napi_create_string_utf8 等;
  • 将 napi 转换成 c++ 的函数: napi_get_value_string_utf8 等;
  • 创建编译器中的 js 对象: napi_create_function 等;
  • 回调 js 函数:napi_call_function

3、NAPI 对象生命周期

NAPI 对象的生命周期代表着从对象创建到释放的整个过程,如下图所示:
在 ArkTS 应用启动时会加载 NAPI 模块,而在 NAPI 模块加载过程中会创建一个对象 A 提供给应用使用,在应用退出或者主动释放 A 对象前,A 对象必须一直保持"活跃"状态。从 A 对象创建到释放的整个过程也代表着 A 对象的生命周期。
在这里插入图片描述
以下是 Node-API 中关于对象生命周期的解释:
当调用 Node-API 时,底层虚拟机在堆中对象的句柄可能以 napi_values 的形式返回。这些句柄必须保持对象“活动”,直到本地代码不再需要它们,更多详情参见链接:

句柄是一个标识符,是用来标识对象的。

未完待续…

转载请注明出处或者链接地址:https://www.qianduange.cn//article/15680.html
标签
harmonyos
评论
发布的文章

JQuery 详细教程

2024-08-21 22:08:08

jQuery2 高级教程(八)

2024-08-21 22:08:06

jQuery Spellchecker 使用教程

2024-08-21 22:08:50

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!