1# Native Bundle Development 2 3## When to Use 4 5Use the native bundle APIs to obtain application information. 6 7## Available APIs 8 9| API | Description | 10| :----------------------------------------------------------- | :--------------------------------------- | 11| [OH_NativeBundle_GetCurrentApplicationInfo](../reference/apis-ability-kit/_bundle.md#oh_nativebundle_getcurrentapplicationinfo) | Obtains the information about the current application. | 12| [OH_NativeBundle_GetAppId](../reference/apis-ability-kit/_bundle.md#oh_nativebundle_getappid) | Obtains the appId information about the application.| 13| [OH_NativeBundle_GetAppIdentifier](../reference/apis-ability-kit/_bundle.md#oh_nativebundle_getappidentifier) | Obtains the appIdentifier information about the application.| 14| [OH_NativeBundle_GetMainElementName](../reference/apis-ability-kit/_bundle.md#oh_nativebundle_getmainelementname) | Obtains the entry information of the application.| 15| [OH_NativeBundle_GetCompatibleDeviceType](../reference/apis-ability-kit/_bundle.md#oh_nativebundle_getcompatibledevicetype) | Obtains the compatible device type of the application.| 16| [OH_NativeBundle_IsDebugMode](../reference/apis-ability-kit/_bundle.md#oh_nativebundle_isdebugmode) | Queries the debug mode of the application.| 17| [OH_NativeBundle_GetModuleMetadata](../reference/apis-ability-kit/_bundle.md#oh_nativebundle_getmodulemetadata) | Obtains the metadata information of the application.| 18 19 20## How to Develop 21 221. Create a project. 23 24 25 26 272. Add dependencies. 28 29After the project is created, the **cpp** directory is created in the project directory. In the **cpp** directory, there are files such as **types/libentry/index.d.ts**, **napi_init.cpp**, and **CMakeLists.txt**. 30 311. Open the **src/main/cpp/CMakeLists.txt** file, and add **libbundle_ndk.z.so** to **target_link_libraries**. 32 33 ```c++ 34 target_link_libraries(entry PUBLIC libace_napi.z.so libbundle_ndk.z.so) 35 ``` 36 372. Open the **src/main/cpp/napi_init.cpp** file, and add the header file. 38 39 ```c++ 40 // Include the header file required for napi. 41 #include "napi/native_api.h" 42 // Include the header file required for NDK interfaces. 43 #include "bundle/native_interface_bundle.h" 44 // Include the standard library for the free() function. 45 #include <cstdlib> 46 ``` 47 483. Modify the source file. 49 501. When the **src/main/cpp/napi_init.cpp** file is opened, **Init** is called to initialize the API. 51 52 ```c++ 53 EXTERN_C_START 54 static napi_value Init(napi_env env, napi_value exports) 55 { 56 napi_property_descriptor desc[] = { 57 { "add", nullptr, Add, nullptr, nullptr, nullptr, napi_default, nullptr }, 58 { "getCurrentApplicationInfo", nullptr, GetCurrentApplicationInfo, nullptr, nullptr, nullptr, napi_default, nullptr}, // Add the getCurrentApplicationInfo API. 59 { "getAppId", nullptr, GetAppId, nullptr, nullptr, nullptr, napi_default, nullptr}, // Add the getAppId API. 60 { "getAppIdentifier", nullptr, GetAppIdentifier, nullptr, nullptr, nullptr, napi_default, nullptr}, // Add the getAppIdentifier API. 61 { "getMainElementName", nullptr, GetMainElementName, nullptr, nullptr, nullptr, napi_default, nullptr}, // Add the getMainElementName method. 62 { "getCompatibleDeviceType", nullptr, GetCompatibleDeviceType, nullptr, nullptr, nullptr, napi_default, nullptr}, // Add the getCompatibleDeviceType method. 63 { "isDebugMode", nullptr, IsDebugMode, nullptr, nullptr, nullptr, napi_default, nullptr}, // Add the isDebugMode method. 64 { "getModuleMetadata", nullptr, GetModuleMetadata, nullptr, nullptr, nullptr, napi_default, nullptr} // Add the getModuleMetadata method. 65 }; 66 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); 67 return exports; 68 } 69 EXTERN_C_END 70 ``` 71 722. Add the API to the **src/main/cpp/napi_init.cpp** file. 73 74 ```c++ 75 static napi_value GetCurrentApplicationInfo(napi_env env, napi_callback_info info); 76 static napi_value GetAppId(napi_env env, napi_callback_info info); 77 static napi_value GetAppIdentifier(napi_env env, napi_callback_info info); 78 static napi_value GetMainElementName(napi_env env, napi_callback_info info); 79 static napi_value GetCompatibleDeviceType(napi_env env, napi_callback_info info); 80 static napi_value IsDebugMode(napi_env env, napi_callback_info info); 81 static napi_value GetModuleMetadata(napi_env env, napi_callback_info info); 823. Obtain the native bundle information object from the **src/main/cpp/napi_init.cpp** file and convert it to a JavaScript bundle information object. In this way, you can obtain the application information on the JavaScript side. 83 84 ```c++ 85 static napi_value GetCurrentApplicationInfo(napi_env env, napi_callback_info info) 86 { 87 // Call the native API to obtain the application information. 88 OH_NativeBundle_ApplicationInfo nativeApplicationInfo = OH_NativeBundle_GetCurrentApplicationInfo(); 89 napi_value result = nullptr; 90 napi_create_object(env, &result); 91 // Convert the bundle name obtained by calling the native API to the bundleName property in the JavaScript object. 92 napi_value bundleName; 93 napi_create_string_utf8(env, nativeApplicationInfo.bundleName, NAPI_AUTO_LENGTH, &bundleName); 94 napi_set_named_property(env, result, "bundleName", bundleName); 95 // Convert the fingerprint information obtained by calling the native API to the fingerprint property in the JavaScript object. 96 napi_value fingerprint; 97 napi_create_string_utf8(env, nativeApplicationInfo.fingerprint, NAPI_AUTO_LENGTH, &fingerprint); 98 napi_set_named_property(env, result, "fingerprint", fingerprint); 99 100 // To prevent memory leak, manually release the memory. 101 free(nativeApplicationInfo.bundleName); 102 free(nativeApplicationInfo.fingerprint); 103 return result; 104 } 105 106 static napi_value GetAppId(napi_env env, napi_callback_info info) 107 { 108 // Call the native API to obtain the appId. 109 char* appId = OH_NativeBundle_GetAppId(); 110 // Convert the appId obtained by calling the native API to nAppId and return it. 111 napi_value nAppId; 112 napi_create_string_utf8(env, appId, NAPI_AUTO_LENGTH, &nAppId); 113 // To prevent memory leak, manually release the memory. 114 free(appId); 115 return nAppId; 116 } 117 118 static napi_value GetAppIdentifier(napi_env env, napi_callback_info info) 119 { 120 // Call the native API to obtain the appIdentifier. 121 char* appIdentifier = OH_NativeBundle_GetAppIdentifier(); 122 // Convert the appIdentifier obtained by calling the native API to nAppIdentifier and return it. 123 napi_value nAppIdentifier; 124 napi_create_string_utf8(env, appIdentifier, NAPI_AUTO_LENGTH, &nAppIdentifier); 125 // To prevent memory leak, manually release the memory. 126 free(appIdentifier); 127 return nAppIdentifier; 128 } 129 130 static napi_value GetMainElementName(napi_env env, napi_callback_info info) 131 { 132 // Call the native API to obtain the application entry information. 133 OH_NativeBundle_ElementName elementName = OH_NativeBundle_GetMainElementName(); 134 napi_value result = nullptr; 135 napi_create_object(env, &result); 136 // Convert the bundle name obtained by calling the native API to the bundleName property in the JavaScript object. 137 napi_value bundleName; 138 napi_create_string_utf8(env, elementName.bundleName, NAPI_AUTO_LENGTH, &bundleName); 139 napi_set_named_property(env, result, "bundleName", bundleName); 140 // Convert the module name obtained by calling the native API to the moduleName property in the JavaScript object. 141 napi_value moduleName; 142 napi_create_string_utf8(env, elementName.moduleName, NAPI_AUTO_LENGTH, &moduleName); 143 napi_set_named_property(env, result, "moduleName", moduleName); 144 // Convert the ability name obtained by calling the native API to the abilityName property in the JavaScript object. 145 napi_value abilityName; 146 napi_create_string_utf8(env, elementName.abilityName, NAPI_AUTO_LENGTH, &abilityName); 147 napi_set_named_property(env, result, "abilityName", abilityName); 148 // To prevent memory leak, manually release the memory. 149 free(elementName.bundleName); 150 free(elementName.moduleName); 151 free(elementName.abilityName); 152 return result; 153 } 154 155 static napi_value GetCompatibleDeviceType(napi_env env, napi_callback_info info) 156 { 157 // Call the native API to obtain the device type. 158 char* deviceType = OH_NativeBundle_GetCompatibleDeviceType(); 159 // Convert the device type obtained by calling the native API to nDeviceType and return it. 160 napi_value nDeviceType; 161 napi_create_string_utf8(env, deviceType, NAPI_AUTO_LENGTH, &nDeviceType); 162 // To prevent memory leak, manually release the memory. 163 free(deviceType); 164 return nDeviceType; 165 } 166 167 static napi_value IsDebugMode(napi_env env, napi_callback_info info) 168 { 169 bool isDebug = false; 170 // Call the native API to obtain the application debug mode. 171 bool isSuccess = OH_NativeBundle_IsDebugMode(&isDebug); 172 // Throw an exception if the native API call fails 173 if (isSuccess == false) { 174 napi_throw_error(env, nullptr, "call failed"); 175 return nullptr; 176 } 177 // Convert the debug information obtained by calling the native API to debug and return it. 178 napi_value debug; 179 napi_get_boolean(env, isDebug, &debug); 180 return debug; 181 } 182 183 static napi_value GetModuleMetadata(napi_env env, napi_callback_info info) 184 { 185 size_t moduleCount = 0; 186 // Call the native API to obtain the application metadata information. 187 OH_NativeBundle_ModuleMetadata* modules = OH_NativeBundle_GetModuleMetadata(&moduleCount); 188 if (modules == nullptr || moduleCount == 0) { 189 napi_throw_error(env, nullptr, "no metadata found"); 190 return nullptr; 191 } 192 193 napi_value result; 194 napi_create_array(env, &result); 195 196 for (size_t i = 0; i < moduleCount; i++) { 197 napi_value moduleObj; 198 napi_create_object(env, &moduleObj); 199 200 // Convert the module name obtained by calling the native API to the moduleName property in the JavaScript object. 201 napi_value moduleName; 202 napi_create_string_utf8(env, modules[i].moduleName, NAPI_AUTO_LENGTH, &moduleName); 203 napi_set_named_property(env, moduleObj, "moduleName", moduleName); 204 205 napi_value metadataArray; 206 napi_create_array(env, &metadataArray); 207 208 for (size_t j = 0; j < modules[i].metadataArraySize; j++) { 209 napi_value metadataObj; 210 napi_create_object(env, &metadataObj); 211 212 napi_value name; 213 napi_value value; 214 napi_value resource; 215 216 napi_create_string_utf8(env, modules[i].metadataArray[j].name, NAPI_AUTO_LENGTH, &name); 217 napi_create_string_utf8(env, modules[i].metadataArray[j].value, NAPI_AUTO_LENGTH, &value); 218 napi_create_string_utf8(env, modules[i].metadataArray[j].resource, NAPI_AUTO_LENGTH, &resource); 219 220 // Convert the metadata name obtained by calling the native API to the name property in the JavaScript object. 221 napi_set_named_property(env, metadataObj, "name", name); 222 // Convert the metadata value obtained by calling the native API to the value property in the JavaScript object. 223 napi_set_named_property(env, metadataObj, "value", value); 224 // Convert the metadata resource obtained by calling the native API to the resource property in the JavaScript object. 225 napi_set_named_property(env, metadataObj, "resource", resource); 226 227 napi_set_element(env, metadataArray, j, metadataObj); 228 } 229 230 napi_set_named_property(env, moduleObj, "metadata", metadataArray); 231 napi_set_element(env, result, i, moduleObj); 232 } 233 234 // To prevent memory leak, manually release the memory. 235 for (size_t i = 0; i < moduleCount; i++) { 236 free(modules[i].moduleName); 237 for (size_t j = 0; j < modules[i].metadataArraySize; j++) { 238 free(modules[i].metadataArray[j].name); 239 free(modules[i].metadataArray[j].value); 240 free(modules[i].metadataArray[j].resource); 241 } 242 free(modules[i].metadataArray); 243 } 244 free(modules); 245 return result; 246 } 247 ``` 248 2494. Expose APIs. 250 251Declare the exposed APIs in the **src/main/cpp/types/libentry/Index.d.ts** file. 252 253```js 254export const add: (a: number, b: number) => number; 255export const getCurrentApplicationInfo: () => object; // Add the exposed API getCurrentApplicationInfo. 256export const getAppId: () => string; // Add the exposed API getAppId. 257export const getAppIdentifier: () => string; // Add the exposed API getAppIdentifier. 258export const getMainElementName: () => object; // Add the exposed API getMainElementName. 259export const getCompatibleDeviceType: () => string; // Add the exposed API getCompatibleDeviceType. 260export const isDebugMode: () => string; // Add the exposed API isDebugMode. 261export const getModuleMetadata: () => object; // Add the exposed API getModuleMetadata. 262``` 263 2645. Call APIs on the JavaScript side. 265 2661. Open the **src\main\ets\pages\index.ets** file, and import **libentry.so**. 267 268 2692. Call the native APIs to print the obtained information. An example is as follows: 270 271 ```js 272 import { hilog } from '@kit.PerformanceAnalysisKit'; 273 import testNapi from 'libentry.so'; 274 275 const DOMAIN = 0x0000; 276 277 @Entry 278 @Component 279 struct Index { 280 @State message: string = 'Hello World'; 281 282 build() { 283 Row() { 284 Column() { 285 Text(this.message) 286 .fontSize($r('app.float.page_text_font_size')) 287 .fontWeight(FontWeight.Bold) 288 .onClick(() => { 289 this.message = 'Welcome'; 290 hilog.info(DOMAIN, 'testTag', 'Test NAPI 2 + 3 = %{public}d', testNapi.add(2, 3)); 291 let appInfo = testNapi.getCurrentApplicationInfo(); 292 console.info("bundleNDK getCurrentApplicationInfo success, data is " + JSON.stringify(appInfo)); 293 let appId = testNapi.getAppId(); 294 console.info("bundleNDK getAppId success, appId is " + appId); 295 let appIdentifier = testNapi.getAppIdentifier(); 296 console.info("bundleNDK getAppIdentifier success, appIdentifier is " + appIdentifier); 297 let mainElement = testNapi.getMainElementName(); 298 console.info("bundleNDK getMainElementName success, data is " + JSON.stringify(mainElement)); 299 let deviceType = testNapi.getCompatibleDeviceType(); 300 console.info("bundleNDK getCompatibleDeviceType success, deviceType is " + deviceType); 301 let isDebugMode = testNapi.isDebugMode(); 302 console.info("bundleNDK isDebugMode success, isDebugMode is " + isDebugMode); 303 let moduleMetadata = testNapi.getModuleMetadata(); 304 console.info("bundleNDK getModuleMetadata success, data is " + JSON.stringify(moduleMetadata)); 305 }) 306 } 307 .width('100%') 308 } 309 .height('100%') 310 } 311 } 312 ``` 313 314For details about the APIs, see [Bundle](../reference/apis-ability-kit/_bundle.md). 315 316<!--no_check-->