#星光计划2.0# OpenHarmony 源码解析之JavaScriptAPI-NAPI实践

Posted HarmonyOS技术社区

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了#星光计划2.0# OpenHarmony 源码解析之JavaScriptAPI-NAPI实践相关的知识,希望对你有一定的参考价值。

作者:卞绍雷

【本文正在参与51CTO HarmonyOS技术社区创作者激励计划-星光计划2.0】

1 简介

开源鸿蒙(OpenHarmony)的APP开发框架是ACE,开发语言是JS/eTS。有时候需要增加一些额外功能,依赖现有的C/C++ 开源库,或者遇到一些CPU密集计算的场合,就需要使用C/C++ 语言来编写更底层的函数,供上层JS调用。

OpenHarmony提供了统一的NAPI接口函数,通过编译系统的裁剪,方便增加新的JS功能模块。

本文以最简单的NAPI接口函数为例,详细说明在OpenHarmony系统如何编写模块文件、本地调试、系统集成、上机测试。

1.1 UI架构相关系列

《OpenHarmony 源码解析之ACE (JavaScript运行环境初始化)》

《OpenHarmony 源码解析之JavaScript API框架(NAPI)》

《OpenHarmony 源码解析之JavaScript API框架(NAPI-C接口)》

《OpenHarmony 源码解析之JavaScript API框架(NAPI实践)》

《OpenHarmony 源码解析之JavaScript(文件管理API)》

1.2 OpenHarmony架构图

1.3 JS UI架构

JS UI框架包括应用层(Application)、前端框架层(Framework)、引擎层(Engine)和平台适配层(Porting Layer),其架构如下图所示:

2 快速实现

建立模块目录,编写基础编译文件

  1. 模块目录理论上可以建立在OpenHarmony代码库的任何地方,为行文方便,假设OpenHarmony代码库的目录为OHOS_SRC,在OHOS_SRC目录下,建立此次测试模块目录:myapp

  2. 此时,OHOS_SRC目录下应该有 ark, foundation, device, ..., myapp 等目录,其中myapp就是刚刚建立的,在myapp目录下,建立以下文件:

    |-- BUILD.gn
    |-- app.cpp
    |-- ohos.build
  3. BUILD.gn:

    ```c++
    import("//build/ohos.gni")
    ohos_shared_library("myapp") {

    指定编译源文件

     sources = [
       "app.cpp",
     ]
     # 指定编译依赖,如果依赖第三方库,需要在此添加
     deps = [ "//foundation/ace/napi:ace_napi" ]
     # 指定库生成的路径
     relative_install_dir = "module"
     # 子系统及其组件,后面会引用
     subsystem_name = "myapp"
     part_name = "myapp_part"

    }

  4. 最终会生成system/lib/module/libmyapp.z.so,并且在APP中:import myapp from @ohos.myapp

  5. 这几处的myapp都是统一名称:

    //myapp指的是myapp目录,:myapp指的是上面BUILD.gn中的目标ohos_shared_library("myapp")

    • ohos.build:

      {
      "subsystem": "myapp",
      "parts": {
       "myapp_part": {
         "module_list": [
           "//myapp:myapp"
         ],
         "test_list": [ ]
       }
      }
      }
    • app.cpp:

    ```c++
    #include <assert.h>

    #include "napi/native_api.h"
    #include "napi/native_node_api.h"

    static napi_value Method(napi_env env, napi_callback_info info) {
    napi_status status;
    napi_value world;
    status = napi_create_string_utf8(env, "Hello, world!", 13, &world);
    assert(status == napi_ok);
    return world;
    }

    static napi_value Init(napi_env env, napi_value exports) {
    napi_status status;
    napi_property_descriptor desc[] = {
    DECLARE_NAPI_FUNCTION("hello", Method),
    };
    status = napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
    assert(status == napi_ok);
    return exports;
    }

    NAPI_MODULE(myapp, Init)

这里只简单写了一个JS模块,只有一个hello函数,返回"Hello, world!"字符串。

3 本地测试

  1. 利用node-gyp进行本地测试,先确保系统安装了node.js

  2. 在myapp目录下,建立test目录,然后编写binding.gyp和test.js文件:

    |-- BUILD.gn
    |-- app.cpp
    |-- ohos.build
    `-- test
       |-- binding.gyp
       `-- test.js
    • binding.gyp:

      按自己系统的实际情况,填写编译器、源代码(sources)、头文件目录(include_dirs)、依赖库(dependencies)、编译参数(cflags、cflags_cc)、链接参数(link_settings: libraries)。

      这里的目标名称(target_name)就是下一步test.js引用测试的名称。

      ```c++
      {
      targets: [
      {
      cc: clang,
      c++: clang++,
      target_name: test-native,
      sources: [ ../app.cpp],
      include_dirs: ["/OHOS_SRC/foundation/ace/napi/interfaces/kits"],
      dependencies: [],
      cflags!: [ -DTESTDEBUG, -std=gnu2x ],
      cflags_cc: [ -DTESTDEBUG, -std=c++17 ],
      link_settings: {
      libraries: []
      },
      }
      ]
      }

    • 接下来,确保系统安装了node-gyp

      如果系统没有安装,那么在测试目录下临时安装也是可以的。

      运行如下命令,确保app.cpp文件无语法错误,可以正确通过编译链接。

      之后如果修改了binding.gyp文件,需要node-gyp rebuild

    • test.js:

      ```c++
      var myapp = require(./build/Release/test-native)
      console.log(myapp)
      console.log(myapp.hello)
      console.log(myapp.hello())

如果编译正常,那么就可以进行本地测试了:

4 集成

集成到系统,在本地测试通过后,各种功能看起来正常,那么就可以集成到OpenHarmony系统,烧录上机测试了。

集成到OpenHarmony的步骤参考鸿蒙子系统的集成步骤:标准系统编译构建指导

这里简单描述一下:

  1. OHOS_SRC/build/subsystem_config.json文件中,增加(注意前后逗号,保持文件格式正确):

     "myapp": {
         "project": "hmf/myapp",
         "path": "myapp",
         "name": "myapp",
         "dir": ""
     }
  2. 在产品配置中添加上述子系统的功能模块,编译到产品产出文件中(注意前后逗号,保持文件格式正确)

  3. 即可开始编译。

  4. 编译完成后,可以在OHOS_SRC/out目录找到生成的.so文件。

    ```c++
    root@1fe862aba551:/home/openharmony# find out -name libmyapp*
    out/ohos-arm-release/packages/phone/NOTICE_FILES/system/lib/module/libmyapp.z.so.txt
    out/ohos-arm-release/packages/phone/system/lib/module/libmyapp.z.so
    out/ohos-arm-release/lib.unstripped/myapp/myapp_part/libmyapp.z.so
    out/ohos-arm-release/myapp/myapp_part/libmyapp.z.so

镜像输出在 out/ohos-arm-release/packages/phone/images/目录下。

5 上机测试及小技巧

第一次编写完成后,需要烧录镜像文件。之后再修改,就可以利用hdc工具,只上传.so文件覆盖原文件即可。

编写测试HAP:

```c++
import myapp from @ohos.myapp
export default {
testGetAppName() {
console.log(myapp.hello())
}
}



假设测试APP的包是com.example.testmyapp,可以使用hdc工具很方便进行的安装、启动、关闭APP等操作。

安装:

> hdc install -r 安装包的本地路径.hap

卸载:

> hdc uninstall com.example.testmyapp

列出已经安装的包:

> hdc shell bm dump -a

启动:

> hdc shell aa start -b com.example.testmyapp -a com.example.testmyapp.MainAbility

关闭:

> hdc shell killall com.example.testmyapp

hdc工具查看日志,可以根据进程号只看测试进程的,这样就更清晰方便了。:

> hdc.exe shell
> ps -elf |grep com.example.testmyapp # 输出的第二列是pid
> hilog -P pid #这里的pid是上面第二列的数字

## 6 小结

OpenHarmony系统的ACE框架已经具备了基础的APP功能,可以很方便的利用NAPI扩展来增强APP,补充JS的不足之处。

##  更多原创内容请关注:[开鸿 HarmonyOS 学院](https://harmonyos.51cto.com/column/59) 

入门到精通、技巧到案例,系统化分享HarmonyOS开发技术,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。

[想了解更多关于鸿蒙的内容,请访问:](https://harmonyos.51cto.com/#bkwz)

[51CTO和华为官方合作共建的鸿蒙技术社区](https://harmonyos.51cto.com/#bkwz)

https://harmonyos.51cto.com/#bkwz

::: hljs-center

![21_9.jpg](https://s2.51cto.com/images/20210924/1632469265578939.jpg?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=)

:::

以上是关于#星光计划2.0# OpenHarmony 源码解析之JavaScriptAPI-NAPI实践的主要内容,如果未能解决你的问题,请参考以下文章

#星光计划2.0# openHarmony轻松连接华为云物联网平台

#星光计划2.0#Openharmony 单元测试1: 测试用例指导大全

#星光计划2.0# OpenHarmony3.0上采用ets开发HAP控制LED灯

#星光计划2.0# linux内核增加HDF驱动子系统

#星光计划2.0# 构建HarmonyOS 3D游戏

#星光计划2.0#基于3861智能开发套件软件开发环境搭建