Harmony Next开发手册:学写一个NAPI子系统

此篇文章,我们主要是熟悉下 NAPI 框架,并一起写一个支持 NAPI 的子系统,这样以后当我们想在 hap 应用里加自己功能的时候就可以方便的添加。

NAPI 框架简介

NAPI(Native API)组件是一套对外接口基于 Node.js N-API 规范开发的原生模块扩展开发框架。类似于 Android 的 JNI,NAPI 框架实现了应用层 ts/ets/js 语言编写的代码和 OpenHarmony 的 native 代码(c/c++)交互的能力。此框架由 Node.js N-API 框架扩展而来。

注意:OpenHarmony 的标准系统是采用 NAPI 框架的,轻量系统则是采用 jerryscript 框架

详细的内容介绍在一下链接内可以看到官方的说明:

参考链接:arkui_napi: Development framework for extending the JS Native Module | 原生模块扩展开发框架

NAPI 的使用

  1. 创建 d.ts: @ohos.napitest.d.ts, basic.d.ts

    • @ohos.napitest.d.ts 是 NAPI 的声明文件,在 DevEco Studio 开发的时候会用到 d.ts 来检查语法和提供代码帮助;
    import {AsyncCallback} from './basic';
    
    /**
     * Provides interfaces to napitest.
     *
     * @since 7
     */
    declare namespace napitest {
      /**
       * Shuts down the system.
       *
       * <p>This method requires the ohos.permission.SHUTDOWN permission.
       *
       * @param reason Indicates the shutdown reason.
       * @systemapi
       * @since 7
       */
      function shutdownDevice(reason: string): void;
    
      /**
       * Restarts the system.
       *
       * <p>This method requires the ohos.permission.REBOOT permission.
       *
       * @param reason Indicates the restart reason. For example, "updater" indicates entering the updater mode
       * after the restart. If the parameter is not specified, the system enters the normal mode after the restart.
       * @since 7
       */
      function rebootDevice(reason: string): void;
    
      /**
       * Checks whether the screen of a device is on or off.
       *
       * @return Returns true if the screen is on; returns false otherwise.
       * @since 7
       */
      function isScreenOn(callback: AsyncCallback<boolean>): void;
      function isScreenOn(): Promise<boolean>;
    }
    export default napitest;
    
    • basic.d.ts:一些基础方法的声明
    export interface Callback<T> {
        (data: T): void;
    }
      
    export interface ErrorCallback<T extends Error = BusinessError> {
        (err: T): void;
    }
    
    export interface AsyncCallback<T> {
        (err: BusinessError, data: T): void;
    }
    
    export interface BusinessError extends Error {
        code: number;
    }
    
  2. 执行 napi_generator
    建立个文件夹,将上面建立的两个 d.ts 和 napi_generator 放在一起

    //准备环境
    mkdir napitest
    cd napitest
    vim @ohos.napitest.d.ts
    vim basic.d.ts
    //拷贝napi_generator
    cp [路径]/napi_generator-linux .
    chmod +x napi_generator-linux
    //生成napitest代码
    ./napi_generator-linux -f @ohos.napitest.d.ts -o out
    //当看到success则说明烧录成功
    
    //检视out目录
    ├── binding.gyp         //工具中间文件
    ├── BUILD.gn            //之后需要用到的gn文件
    ├── napi_gen.log        //工具log
    ├── napitest.cpp        //自动生成的接口调用的实际代码
    ├── napitest.h          //自动生成的接口调用的实际代码
    ├── napitest_middle.cpp //自动生成的napi适配代码
    ├── test.sh             //生成js代码的脚本,官方没给说明,试了下不可用
    ├── tool_utility.cpp    //自动生成的napi适配代码
    └── tool_utility.h      //自动生成的napi适配代码
    
  3. 建立子系统

    • 在 OpenHarmony 源码目录下建立 foundation/napitest,将之前生成的文件拷贝到文件夹内
    foundation
    ├── ability
    ├── ai
    ├── arkui
    ├── barrierfree
    ├── bundlemanager
    ├── communication
    ├── deviceprofile
    ├── distributeddatamgr
    ├── distributedhardware
    ├── filemanagement
    ├── graphic
    ├── multimedia
    ├── multimodalinput
    ├── napitest
    │   ├── binding.gyp
    │   ├── BUILD.gn
    │   ├── bundle.json
    │   ├── napi_gen.log
    │   ├── napitest.cpp
    │   ├── napitest.h
    │   ├── napitest_middle.cpp
    │   ├── test.sh
    │   ├── tool_utility.cpp
    │   └── tool_utility.h
    ├── resourceschedule
    
    • 在目录里创建 bundle.json,使用一下内容
    {
        "name": "@ohos/napitest",
        "description": "napitest provides atomic capabilities",
        "version": "3.1",
        "license": "Apache License 2.0",
        "publishAs": "code-segment",
        "segment": {
          "destPath": "foundation/napitest"
        },
        "dirs": {},
        "scripts": {},
        "component": {
          //部件名称
          "name": "napitest_interface",
          //子系统名称
          "subsystem": "napitest",
          "features": [],
          "adapted_system_type": [
            "standard"
          ],
          "rom": "10000KB",
          "ram": "10000KB",
          "deps": {
            "components": [
              "ace_napi",
              "ipc_core",
              "libhilog"
            ],
            "third_party": [
              "node"
            ]
          },
          "build": {
            "sub_component": [
              "//foundation/napitest:napitest"
            ],
            "inner_kits": [
              {
                "header": {
                  "header_base": "//foundation/napitest",
                  "header_files": [
                    "tool_utility.h",
                    "napitest.h"
                  ]
                },
                "name": "//foundation/napitest:napitest"
              }
            ]
          }
        }
      }
    
    • 为了和 bundle.json 对应,将 BUILD.gn 改成如下:
    import("//build/ohos.gni")
    
    ohos_shared_library("napitest")
    {
        sources = [
            "napitest_middle.cpp",
            "napitest.cpp",
            "tool_utility.cpp",
        ]
        include_dirs = [
            ".",
            "//third_party/node/src",
            "//base/hiviewdfx/hilog/interfaces/native/innerkits/include",
        ]
        deps=[
            "//foundation/arkui/napi:ace_napi",
            "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog",
        ]
        remove_configs = [ "//build/config/compiler:no_rtti" ]
        cflags=[
        ]
        cflags_cc=[
            "-frtti",
        ]
        ldflags = [
        ]
        
        relative_install_dir = "module"
        //部件名称
        part_name = "napitest_interface"
        //子系统名称
        subsystem_name = "napitest"
    }
    
  4. 引入子系统

    • 增加子系统,修改 build/subsystem_config.json
      //在文件后增加
      {
        //前面省略的内容
          ...
        //新增内容
        "napitest": {
          "path": "foundation/napitest",
          "name": "napitest"
        }
      }
      
    • 增加编译入口(已目前的 master 版本为基础,3.2 后改过编译路径)
      //修改 vendor/hihope/[PRODUCT_NAME]/config.json 文件增加如下行
      {
          "subsystem": "napitest",
          "components": [
          {
              "component": "napitest_interface",
              "features": []
          }
          ]
      },
      
  5. 编译生成

    ./build.sh --product-name PRODUCT_NAME
    //看到success则为编译成功,可以通过find out/[PRODUCT_NAME] -name *napitest.z.so查看生成文件,比如我的文件路径如下:
    ./out/rk3568/lib.unstripped/napitest/napitest_interface/libnapitest.z.so
    ./out/rk3568/napitest/napitest_interface/libnapitest.z.so
    ./out/rk3568/innerkits/ohos-arm/napitest_interface/napitest/libnapitest.z.so
    ./out/rk3568/packages/phone/system/lib/module/libnapitest.z.so
    //最后一个路径就是系统镜像的路径,所以两种办法
    //1,直接copy到板子的/system/lib路径;
    //2,烧录镜像;
    
    
    
总结

这样我们就有了自己的 subsystem 和 napi 接口

  • 24
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值