天天看点

OpenHarmony NAPI模块注册流程

作者:51CTO

关于 NAPI 接口相关知识,之前我们介绍过 NAPI 同步异步接口使用方法、应用启动触发的 ArkUI ets_runtime 启动流程,从 NAPI 使用到整体流程给大家做了介绍。

OpenHarmony NAPI模块注册流程

本次我们针对 NAPI 模块注册流程做深入介绍,给大家后续工作中开发、使用 NAPI 接口提供指导。

模块注册简介

NAPI 模块注册是在系统框架层与应用层的相互配合下完成的,下面简要介绍一下大致流程。

OpenHarmony NAPI模块注册流程

首先,提供 NAPI 接口定义给应用层,一般是打包到 SDK 中,供应用开发者查询使用;其次,NAPI 接口在框架层实现其业务逻辑代码后。

最后,在编译脚本中定义模块对外接口方法,可以是静态库或者动态库,也可以是可执行文件方式。

当前 OpenHarmony 库中 NAPI 模块,大多通过动态库方式加载。

OpenHarmony NAPI模块注册流程

对于应用层,首先引用需要的 NAPI 所在的库名,然后通过库名调用模块内相应的接口。

OpenHarmony NAPI模块注册流程

上面我们简要介绍了 NAPI 模块注册的流程,接下来我们对应用层如何触发 NAPI 模块加载、模块注册,以及系统框架层在收到加载、注册请求后如何处理,进而调用到引擎层面。

注册流程详解

①模块注册

OpenHarmony NAPI模块注册流程

Ability 线程初始化

应用 hap 包安装到设备后,启动应用程序时,通过 foundation 进程 fork 出应用进程,应用进程的主线程。

根据包中的应用类型(FA 或 Stage)、 UI 风格(js 或 ets)初始化 Ability,我们以 FA 模型、ets UI 为例,展开描述。

Ability 初始化时,会判断当前 Ability 类型(AceAbility、PageAbility、ServiceAblity 等),进而调用相应类型 Ability 的初始化。

在 AceAbility 初始化时,需要先创建 AceContainer,后续可以通过 AceContainer 获取包信息、窗口信息。

创建 AceContainer 时,需要初始化 UI 前端,以及初始化引擎,引擎初始化时,前端会拉起 js 线程,进而进入 UI 后端引擎初始化流程。

js 线程初始化

js 线程进行后端引擎初始化时,首先进行 js Runtime 初始化,在运行环境中创建 js 虚拟机 vm,根据虚拟机创建 NativeEngine。

NativeEgine 会根据后端引擎类型,调用相应的子类 NativeEgine,目前标准系统支持的后端引擎:QuickJS 引擎、Ark 引擎,编译选项可自定义引擎类型,此处我们以 ark 引擎为例讲解。

应用代码中的:

import XXX from "@ohos.xxx"           

经过前端处理打包后,生成的代码为映射为:

globalThis.requireNapi("xxx")           

创建后端 ark 引擎时,会定义 requireNapi 接口,接口中通过模块管理器加载模块。

加载模块时,首先从缓存中查找已加载的模块是否匹配,首次加载的模块缓存中是不存在的,查找失败;缓存中查找失败后,则从硬盘中加载,首次加载均是从硬盘加载。

库加载成功后,根据已加载的 nativeModule 回调 NAPI 模块注册时定义的回调函数。

②模块选择

模块选择时,首先从缓存的已加载模块中匹配是否存在需要的模块,若存在则直接用缓存的进行后续接口查找。否则从硬盘中加载库,根据注册信息获取模块信息。

FindNativeModuleByCache:

OpenHarmony NAPI模块注册流程

从缓存中查找模块时,根据 import 模块名查找是否被 load 过(nm_modname),若查找不成功,则从硬盘中加载库。

否则,继续检查模块是否被加载过,若被加载过,则返回模块信息,进行后续接口处理;若未被加载,则要查找的模块插入已加载模块链表尾部;进行后续从硬盘中加载库。

FindNativeModuleByDisk:

OpenHarmony NAPI模块注册流程

从硬盘中加载库时,首先调用 GetNativeModulePath 获取对应的库路径,选路径时,首先将要查找的库名进行小写处理,然后获取匹配首选路径、备选路径(首先路径_napi)。

然后依次匹配,若查找成功,则会调用 dlopen 打开库,首次 dlopen 时,会调用库的构造回调进行已加载模块注册处理,将模块信息写到已加载模块链表中;至此模块注册、查找流程结束。

总结

本文介绍了 NAPI 模块注册流程,后续大家开发中需要注意以下几点:

  • 库名一定要小写
  • 模块名与库名要一致,大小写可不一致
  • 库名 AA、AA_napi 均能匹配成功,优先匹配 AA
  • 应用首次调用接口时触发模块注册

关于 NAPI 框架原理介绍会持续更新,感谢大家关注。

作者:赵军霞

继续阅读