作者:王石
在《#跟着小白一起學鴻蒙#[六]第一個hap應用》我們熟悉了如何在開源鴻蒙開發hap應用,後期的文章我們會寫在hap應用裡調用系統庫甚至是動态庫。此篇文章,我們主要是熟悉下NAPI架構,并一起寫一個支援NAPI的子系統,這樣以後當我們想在hap應用裡加自己功能的時候就可以友善的添加。
NAPI架構簡介
NAPI(Native API)元件是一套對外接口基于Node.js N-API規範開發的原生子產品擴充開發架構。類似于Android的JNI,NAPI架構實作了應用層ts/ets/js語言編寫的代碼和開源鴻蒙的native代碼(c/c++)互動的能力。此架構由Node.js N-API架構擴充而來。
注意:開源鴻蒙的标準系統是采用NAPI架構的,輕量系統則是采用jerryscript架構
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIxkTNfhGLwIDOfdHLlpXazVmcvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5iNmZDZmRjYzMGZmBjY1EmM3MTOyMmMlRTM4UGZ4gDO0YzN3ETMw8CX5AjMyAjMvw1cldWYtl2Lc12bj5yb0NWM14ycvlnbv1mchhWLsR2Lc9CX6MHc0RHaiojIsJye.png)
詳細的内容介紹在一下連結内可以看到官方的說明:
參考連結:https://gitee.com/openharmony/arkui_napi
NAPI的使用
graph LR
建立d.ts --> 執行napi_generator --> 建立子系統 --> 引入子系統 --> 編譯生成
- 建立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; }
-
執行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适配代碼
- 建立子系統
- 在鴻蒙源碼目錄下建立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" }
- 引入子系統
- 增加子系統,修改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": [] } ] },
- 增加子系統,修改build/subsystem_config.json
- 編譯生成
./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路徑;參考《#跟着小白一起學鴻蒙# [二]第一個OpenHarmony程式》 //2,燒錄鏡像;參考《#跟着小白一起學鴻蒙# [一]運作OpenHarmony》
總結
這樣我們就有了自己的subsystem和napi接口,後面的章節我們會講如何在hap應用裡調用系統庫
參考連結:https://gitee.com/openharmony/napi_generator/tree/master
附件連結:https://ost.51cto.com/resource/2308