OpenHarmony 源碼解析之JavaScriptAPI-NAPI 實踐
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)
1、簡介
開源鴻蒙(OpenHarmony)的APP開發(fā)框架是ACE,開發(fā)語言是JS/eTS。有時候需要增加一些額外功能,依賴現(xiàn)有的C/C++ 開源庫,或者遇到一些CPU密集計算的場合,就需要使用C/C++ 語言來編寫更底層的函數(shù),供上層JS調(diào)用。
OpenHarmony提供了統(tǒng)一的NAPI接口函數(shù),通過編譯系統(tǒng)的裁剪,方便增加新的JS功能模塊。
本文以最簡單的NAPI接口函數(shù)為例,詳細說明在OpenHarmony系統(tǒng)如何編寫模塊文件、本地調(diào)試、系統(tǒng)集成、上機測試。
1.1 UI架構(gòu)相關(guān)系列
- 《OpenHarmony 源碼解析之ACE (JavaScript運行環(huán)境初始化)》
- 《OpenHarmony 源碼解析之JavaScript API框架(NAPI)》
- 《OpenHarmony 源碼解析之JavaScript API框架(NAPI-C接口)》
- 《OpenHarmony 源碼解析之JavaScript API框架(NAPI實踐)》
- 《OpenHarmony 源碼解析之JavaScript(文件管理API)》
1.2 OpenHarmony架構(gòu)圖

1.3 JS UI架構(gòu)
JS UI框架包括應用層(Application)、前端框架層(Framework)、引擎層(Engine)和平臺適配層(Porting Layer),其架構(gòu)如下圖所示:

2、快速實現(xiàn)
建立模塊目錄,編寫基礎編譯文件
模塊目錄理論上可以建立在OpenHarmony代碼庫的任何地方,為行文方便,假設OpenHarmony代碼庫的目錄為OHOS_SRC,在OHOS_SRC目錄下,建立此次測試模塊目錄:myapp。
此時,OHOS_SRC目錄下應該有 ark, foundation, device, …, myapp 等目錄,其中myapp就是剛剛建立的,在myapp目錄下,建立以下文件:
- |-- BUILD.gn
- |-- app.cpp
- |-- ohos.build
BUILD.gn:
- import("//build/ohos.gni")
- ohos_shared_library("myapp") {
- # 指定編譯源文件
- sources = [
- "app.cpp",
- ]
- # 指定編譯依賴,如果依賴第三方庫,需要在此添加
- deps = [ "//foundation/ace/napi:ace_napi" ]
- # 指定庫生成的路徑
- relative_install_dir = "module"
- # 子系統(tǒng)及其組件,后面會引用
- subsystem_name = "myapp"
- part_name = "myapp_part"
- }
最終會生成system/lib/module/libmyapp.z.so,并且在APP中:import myapp from '@ohos.myapp'
這幾處的myapp都是統(tǒng)一名稱:
- “module_list”: [ “//myapp: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:
- #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函數(shù),返回"Hello, world!"字符串。
3、本地測試
利用 node-gyp進行本地測試,先確保系統(tǒng)安裝了node.js。
- node --version
在myapp目錄下,建立test目錄,然后編寫binding.gyp和test.js文件:
- |-- BUILD.gn
- |-- app.cpp
- |-- ohos.build
- `-- test
- |-- binding.gyp
- `-- test.js
binding.gyp:
按自己系統(tǒng)的實際情況,填寫編譯器、源代碼(sources)、頭文件目錄(include_dirs)、依賴庫(dependencies)、編譯參數(shù)(cflags、cflags_cc)、鏈接參數(shù)(link_settings: libraries)。
這里的目標名稱(target_name)就是下一步test.js引用測試的名稱。
- {
- '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': ['']
- },
- }
- ]
- }
接下來,確保系統(tǒng)安裝了node-gyp
- node-gyp --version
如果系統(tǒng)沒有安裝,那么在測試目錄下臨時安裝也是可以的。
- cd OHOS_SRC/myapp/test
- npm install node-gyp
- ./node_modules/.bin/node-gyp --version
運行如下命令,確保app.cpp文件無語法錯誤,可以正確通過編譯鏈接。
- cd OHOS_SRC/myapp/test
- node-gyp configure
- node-gyp build
之后如果修改了binding.gyp文件,需要node-gyp rebuild,
test.js:
- var myapp = require('./build/Release/test-native')
- console.log(myapp)
- console.log(myapp.hello)
- console.log(myapp.hello())
如果編譯正常,那么就可以進行本地測試了:
- node test.js
4、集成
集成到系統(tǒng),在本地測試通過后,各種功能看起來正常,那么就可以集成到OpenHarmony系統(tǒng),燒錄上機測試了。
集成到OpenHarmony的步驟參考鴻蒙子系統(tǒng)的集成步驟:標準系統(tǒng)編譯構(gòu)建指導
這里簡單描述一下:
在OHOS_SRC/build/subsystem_config.json文件中,增加(注意前后逗號,保持文件格式正確):
- "myapp": {
- "project": "hmf/myapp",
- "path": "myapp",
- "name": "myapp",
- "dir": ""
- }
在產(chǎn)品配置中添加上述子系統(tǒng)的功能模塊,編譯到產(chǎn)品產(chǎn)出文件中(注意前后逗號,保持文件格式正確)
- OHOS_SRC/productdefine/common/products/產(chǎn)品名稱.json
- “myapp:myapp_part”:{}
即可開始編譯。
- ./build.sh --product-name 產(chǎn)品名稱
編譯完成后,可以在OHOS_SRC/out目錄找到生成的.so文件。
- 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文件覆蓋原文件即可。
- hdc.exe file send libmyapp.z.so system/lib/module/libmyapp.z.so
編寫測試HAP:
- import myapp from '@ohos.myapp'
- export default {
- testGetAppName() {
- console.log(myapp.hello())
- }
- }
假設測試APP的包是com.example.testmyapp,可以使用hdc工具很方便進行的安裝、啟動、關(guān)閉APP等操作。
安裝:
- hdc install -r 安裝包的本地路徑.hap
卸載:
- hdc uninstall com.example.testmyapp
列出已經(jīng)安裝的包:
- hdc shell bm dump -a
啟動:
- hdc shell aa start -b com.example.testmyapp -a com.example.testmyapp.MainAbility
關(guān)閉:
- hdc shell killall com.example.testmyapp
hdc工具查看日志,可以根據(jù)進程號只看測試進程的,這樣就更清晰方便了。:
- hdc.exe shell
- ps -elf |grep com.example.testmyapp # 輸出的第二列是pid
- hilog -P pid #這里的pid是上面第二列的數(shù)字
6、小結(jié)
OpenHarmony系統(tǒng)的ACE框架已經(jīng)具備了基礎的APP功能,可以很方便的利用NAPI擴展來增強APP,補充JS的不足之處。
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)