The foundation/arkui/napi repository contains a development framework for extending the JS Native Module and provides APIs developed based on Node.js N-API for external use.
-
NativeEngine
NativeEngine is the JS engine abstraction layer. It unifies API behavior of the JS engines at the NAPI layer.
-
ModuleManager
ModuleManager is used to load modules and cache module information.
-
ScopeManager
ScopeManager manages the NativeValue lifecycle.
-
ReferenceManager
ReferenceManager manages the NativeReference lifecycle.
The source code directory structure of this repository is as follows:
foundation/arkui/napi
├── interfaces
│ └── kits
│ └── napi # NAPI header files
├── module_manager # Module manager
├── native_engine # NativeEngine abstraction layer
│ └── impl
│ └── ark # Ark-based NativeEngine implementation
├── scope_manager # Scope manager
└── test # Test code
NAPI is suitable for processing I/O- and CPU-intensive tasks and system tasks. It encapsulates the capabilities and provides them to apps as JS APIs. NAPI can be used to implement mutual access between JS and C/C++ code. You can use NAPI to develop modules such as network communications, serial port access, multimedia decoding, and sensor data collection.
For details about the API implementation, see the foundation/arkui/napi repository.
Table 1 Available NAPIs
Provides APIs executing ===, typeof, instanceof, and other operations alike. |
|
Provides functions for performing operations on object properties. |
|
The following example describes how to use NAPI to develop a JS API for obtaining the application bundle name.
The prototype of the JS API is as follows:
function getAppName(): string;
The implementation code of the JS API is as follows:
// app.cpp
#include <stdio.h>
#include <string.h>
#include "napi/native_api.h"
#include "napi/native_node_api.h"
struct AsyncCallbackInfo {
napi_env env;
napi_async_work asyncWork;
napi_deferred deferred;
};
// C/C++ function corresponding to getAppName()
napi_value JSGetAppName(napi_env env, napi_callback_info info) {
napi_deferred deferred;
napi_value promise;
// Create a promise.
NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
AsyncCallbackInfo* asyncCallbackInfo = new AsyncCallbackInfo {
.env = env,
.asyncWork = nullptr,
.deferred = deferred,
};
napi_value resourceName;
napi_create_string_latin1(env, "GetAppName", NAPI_AUTO_LENGTH, &resourceName);
// Create a queue of asynchronous tasks.
napi_create_async_work(
env, nullptr, resourceName,
// Callback for an asynchronous task
[](napi_env env, void* data) {},
// Callback after the asynchronous task is complete
[](napi_env env, napi_status status, void* data) {
AsyncCallbackInfo* asyncCallbackInfo = (AsyncCallbackInfo*)data;
napi_value appName;
const char* str = "com.example.helloworld";
napi_create_string_utf8(env, str, strlen(str), &appName);
// Trigger the callback.
napi_resolve_deferred(asyncCallbackInfo->env, asyncCallbackInfo->deferred, appName);
napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
delete asyncCallbackInfo;
},
(void*)asyncCallbackInfo, &asyncCallbackInfo->asyncWork);
napi_queue_async_work(env, asyncCallbackInfo->asyncWork);
return promise;
}
// Export the module.
static napi_value AppExport(napi_env env, napi_value exports)
{
static napi_property_descriptor desc[] = {
DECLARE_NAPI_FUNCTION("getAppName", JSGetAppName),
};
NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
return exports;
}
// App module description
static napi_module appModule = {
.nm_version = 1,
.nm_flags = 0,
.nm_filename = nullptr,
.nm_register_func = AppExport,
.nm_modname = "app",
.nm_priv = ((void*)0),
.reserved = {0}
};
// Register the module.
extern "C" __attribute__((constructor)) void AppRegister()
{
napi_module_register(&appModule);
}
The build script is as follows:
// BUILD.gn
import("//build/ohos.gni")
ohos_shared_library("app") {
# Specify the source file to build.
sources = [
"app.cpp",
]
# Specify build dependencies.
deps = [ "//foundation/arkui/napi:ace_napi" ]
# Specify the directory where the library is generated.
relative_install_dir = "module"
subsystem_name = "arkui"
part_name = "napi"
}
Test code to run in your app is as follows:
import app from '@ohos.app'
export default {
testGetAppName() {
app.getAppName().then(function (data) {
console.info('app name: ' + data);
});
}
}
arkui_napi