From 33d4077edd3abfc89463f065259ab6572593e103 Mon Sep 17 00:00:00 2001 From: "ester.zhou" Date: Thu, 13 Apr 2023 20:26:35 +0800 Subject: [PATCH] Update docs (16425) Signed-off-by: ester.zhou --- .../quick-start/app-configuration-file.md | 9 +- .../application-package-structure-fa.md | 2 +- .../application-package-structure-stage.md | 2 +- .../quick-start/atomicService.md | 218 ++++++++++++++++ .../figures/application_details.jpg | Bin 0 -> 66956 bytes .../quick-start/module-configuration-file.md | 245 ++++++++++++------ .../quick-start/module-structure.md | 84 +++--- .../quick-start/multi-hap-objective.md | 8 +- 8 files changed, 422 insertions(+), 146 deletions(-) create mode 100644 en/application-dev/quick-start/atomicService.md create mode 100644 en/application-dev/quick-start/figures/application_details.jpg diff --git a/en/application-dev/quick-start/app-configuration-file.md b/en/application-dev/quick-start/app-configuration-file.md index f68ec8ee66..cbc97f24e8 100644 --- a/en/application-dev/quick-start/app-configuration-file.md +++ b/en/application-dev/quick-start/app-configuration-file.md @@ -19,7 +19,9 @@ This document gives an overview of the **app.json5** configuration file. To star "debug": false, "car": { "minAPIVersion": 8, - } + }, + "targetBundleName": "com.application.test", + "targetPriority": 50 }, } ``` @@ -28,11 +30,12 @@ This document gives an overview of the **app.json5** configuration file. To star As shown above, the **app.json5** file contains several tags. -**Table 1** Tags in the app.json5 file + **Table 1** Tags in the app.json5 file | Name| Description| Data Type| Initial Value Allowed| | -------- | -------- | -------- | -------- | | bundleName | Bundle name, which uniquely identifies an application. The value must comply with the following rules:
- Consists of letters, digits, underscores (_), and periods (.).
- Starts with a letter.
- Contains 7 to 127 bytes.
You are advised to use the reverse domain name notation, for example, *com.example.demo*, where the first part is the domain suffix **com**, the second part is the vendor/individual name, and the third part is the application name, which can be of multiple levels.
If an application is built with the system source code, you are advised to name it in *com.ohos.demo* notation, where **ohos** signifies that the application is an OpenHarmony system application.| String| No| +| bundleType| Bundle type, which is used to distinguish applications and atomic services.
- **app**: The bundle is a common application.
- **atomicService**: The bundle is an atomic service.
- **shared**: The bundle is a shared object application. | String| Yes (initial value: **"app"**)| | debug | Whether the application can be debugged. This tag is generated during compilation and building in DevEco Studio.
- **true**: The application can be debugged.
- **false**: The application cannot be debugged.| Boolean| Yes (initial value: **false**)| | icon | [Icon of the application](../application-models/application-component-configuration-stage.md). The value is an icon resource index.| String| No| | label | [Name of the application](../application-models/application-component-configuration-stage.md). The value is a string resource index.| String| No| @@ -51,3 +54,5 @@ As shown above, the **app.json5** file contains several tags. | wearable | Wearable-specific configuration, which includes **minAPIVersion** and **distributedNotificationEnabled** attributes.
When running on wearables, the application applies the attribute settings under this tag and ignores the general counterparts.| Object| Yes (initial value: general settings in the **app.json5** file)| | car | Head unit–specific configuration, which includes **minAPIVersion** and **distributedNotificationEnabled** attributes.
When running on head units, the application applies the attribute settings under this tag and ignores the general counterparts.| Object| Yes (initial value: general settings in the **app.json5** file)| | default | Default device–specific configuration, which includes **minAPIVersion** and **distributedNotificationEnabled** attributes.
When running on default devices, the application applies the attribute settings under this tag and ignores the general counterparts.| Object| Yes (initial value: general settings in the **app.json5** file)| +|targetBundleName|Target application name of the bundle. The value rule and range are the same as those of **bundleName**.|String|Yes (if the initial value is used, the target application is not an application with the overlay feature)| +|targetPriority|Priority of the application. When **targetBundleName** is set, the application is an application with the overlay feature. The value ranges from 1 to 100.|Number|Yes (initial value: **1**)| diff --git a/en/application-dev/quick-start/application-package-structure-fa.md b/en/application-dev/quick-start/application-package-structure-fa.md index 6909481445..a9d647385f 100644 --- a/en/application-dev/quick-start/application-package-structure-fa.md +++ b/en/application-dev/quick-start/application-package-structure-fa.md @@ -11,7 +11,7 @@ The difference between the application package structures in the FA model and st - The **assets** folder is a collection of all the resource files, library files, and code files in a HAP file. It can be further organized into the **entry** folder and the **js** folder. The **entry** folder stores the **resources** folder and the **resources.index** file. -- The **resources** folder stores resource files (such as strings and images) of the application. +- The **resources** folder stores resource files (such as strings and images) of the application. For details, see [Resource Categories and Access](resource-categories-and-access.md). - The **resources.index** file provides a resource index table, which is generated by DevEco Studio invoking the specific SDK tool. diff --git a/en/application-dev/quick-start/application-package-structure-stage.md b/en/application-dev/quick-start/application-package-structure-stage.md index cb6dc3b12e..0736157fd4 100644 --- a/en/application-dev/quick-start/application-package-structure-stage.md +++ b/en/application-dev/quick-start/application-package-structure-stage.md @@ -22,7 +22,7 @@ To develop an application based on the [stage model](application-configuration-f - The HAP file includes folders such as **ets**, **libs**, and **resources** and files such as **resources.index**, **module.json**, and **pack.info**. - The **ets** folder stores bytecode files generated after application code build. - The **libs** folder stores library files, which are .so binary files that contain third-party code on which the OpenHarmony application depends. - - The **resources** folder stores resource files (such as strings and images) of the application. + - The **resources** folder stores resource files (such as strings and images) of the application. For details, see [Resource Categories and Access](resource-categories-and-access.md). - The **resources.index** file provides a resource index table, which is generated when the application project is built in DevEco Studio. - The **module.json** file is the configuration file indispensable in a HAP file. It consists of **module.json5** and **app.json5** in the project configuration. While DevEco Studio provides default configuration, you must modify the configuration as needed. For details about the configuration fields, see [Application Configuration Files in Stage Model](application-configuration-file-overview-stage.md). - The **pack.info** file describes the HAP attributes in the bundle, for example, **bundleName** and **versionCode** in **app** and **name**, **type**, and **abilities** in **module**. The file is automatically generated when DevEco Studio generates the bundle. diff --git a/en/application-dev/quick-start/atomicService.md b/en/application-dev/quick-start/atomicService.md new file mode 100644 index 0000000000..2c2216bfc2 --- /dev/null +++ b/en/application-dev/quick-start/atomicService.md @@ -0,0 +1,218 @@ +# Atomic Service + +## Pre-loading by HAP Type + +### HAP File Implementation + +To speed up the initial startup of an atomic service, you can configure it to load on demand with the use of HAP files. HAP files of an atomic service are classified as entry-type or feature-type. The entry-type HAP file contains the page code and related resources required for starting up the atomic service. The feature-type HAP files contain the rest of the code and resources. To start the atomic service, the user only needs to download and install the entry-type HAP file, which minimizes the time for downloading the atomic service. + +#### How to Use + +You create HAP files of an atomic service by creating an atomic service project in DevEco Studio. The basic project directory structure is as follows: + +``` +├── AppScope +| ├── resources +| └── app.json5 +├── entry +| └── src/main +| ├── ets +| ├── resources +| └── module.json5 +├── feature +| └── src/main +| ├── ets +| ├── resources +| └── module.json5 +├── library +| └── src/main +| ├── ets +| ├── resources +| └── module.json5 +├── node_modules +``` + +Note that you must set the **bundleType** field to **atomicService** in the [app.json5](app-configuration-file.md) file, which is located in the **AppScope** folder. The following is an example of the file content: + +```json +{ + "app": { + "bundleName": "com.example.hmservice", + "bundleType":"atomicService", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:app_icon", + "label": "$string:app_name", + "distributedNotificationEnabled": true, + "targetAPIVersion": 9 + } +} +``` + +For details about HAP files, see [Multi-HAP Design Objectives](multi-hap-objective.md). + +#### Restrictions + +1. The **installationFree** field must be set to **true** in each module-specific configuration file [module.json5](module-configuration-file.md) file. + +2. When packaging an atomic service, comply with the following size rules: + +- The total size of HAP files cannot exceed 10 MB. + +- The size of a HAP file itself and all its dependent [HSP](in-app-hsp.md) cannot exceed 2 MB. + + +### Pre-loading Implementation + +You can configure the system to automatically pre-download required modules when the atomic service enters a module, thereby speeding up module access. + +Currently, pre-loading can be implemented only through configuration, not by invoking APIs. + +#### How to Use + +Pre-loading is triggered after the first frame of the newly accessed module is rendered. You can configure what to pre-load for a module, by setting the **preloads** field under **atomicService** in the [module.json5](module-configuration-file.md) file of the module. The following is an example of the **module.json5** file of the **entry** module, saved in **entry/src/main**: + +```json +{ + "module": { + "name": "entry", + "type": "entry", + "srcEntrance": "./ets/Application/MyAbilityStage.ts", + "description": "$string:entry_desc", + "mainElement": "MainAbility", + "deviceTypes": [ + "default", + "tablet" + ], + "deliveryWithInstall": true, + "installationFree": true, + "pages": "$profile:main_pages", + "atomicService": { + "preloads": [ + { + "moduleName": "feature" + } + ] + }, + "abilities": [ + { + "name": "MainAbility", + "srcEntrance": "./ets/MainAbility/MainAbility.ts", + "description": "$string:MainAbility_desc", + "icon": "$media:icon", + "label": "$string:MainAbility_label", + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:white", + "visible": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ] + } +} +``` + +In this example, the system automatically pre-loads the **feature** module after the first frame of the **entry** module is rendered. + +#### Restrictions + +[moduleType](../reference/apis/js-apis-bundleManager.md#moduletype) corresponding to moduleName in the **preloads** list cannot be entry. + +## Using Dynamic Shared Packages in Atomic Services + +A [Harmony Shared Package (HSP)](shared-guide.md) is a dynamic shared package for sharing code, C++ libraries, resources, and configuration files among modules. +For details about how to use the HSP within an atomic service, see [In-Application HSP Development](in-app-hsp.md). + +#### How to Use + +Assume that the project directory structure is as follows: +``` +├── AppScope +| ├── resources +| └── app.json5 +├── entry +| └── src/main +| ├── ets +| ├── entryAbility +| └── pages +| └── Index.ets +| ├── resources +| └── module.json5 +├── feature +| └── src/main +| ├── ets +| ├── resources +| └── module.json5 +├── library +| └── src/main +| ├── ets +| └── pages +| └── menu.ets +| ├── resources +| └── module.json5 +├── node_modules +``` + +If you want to add a button in the **entry** module to jump to the menu page (**library/src/main/ets/pages/menu.ets**) in the **library** module, you can write the following code in the **entry/src/main/ets/MainAbility/Index.ets** file of the **entry** module: + +```ts +import router from '@ohos.router'; + +@Entry +@Component +struct Index { + @State message: string = 'Hello World' + + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + // Add a button to respond to user clicks. + Button() { + Text('click to menu') + .fontSize(30) + .fontWeight(FontWeight.Bold) + } + .type(ButtonType.Capsule) + .margin({ + top: 20 + }) + .backgroundColor('#0D9FFB') + .width('40%') + .height('5%') + // Bind click events. + .onClick(() => { + router.pushUrl({ + url: '@bundle:com.example.hmservice/library/ets/pages/menu' + }).then(() => { + console.log("push page success"); + }).catch(err => { + console.error(`pushUrl failed, code is ${err.code}, message is ${err.message}`); + }) + } + .width('100%') + } + .height('100%') + } +} +``` + +The input parameter **url** of the **router.pushUrl** API is as follows: +```ets +'@bundle:com.example.hmservice/library/ets/pages/menu' +``` +The **url** content template is as follows: +```ets +'@bundle:bundle name/module name/path/page file name (without the extension .ets)' +``` diff --git a/en/application-dev/quick-start/figures/application_details.jpg b/en/application-dev/quick-start/figures/application_details.jpg new file mode 100644 index 0000000000000000000000000000000000000000..02524b549eaf636e2a8a0f2ec869513d99f1a161 GIT binary patch literal 66956 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 **true**: The HAP file will be installed when the user installs the application.
- **false**: The HAP file will not be installed when the user installs the application.| Boolean| No| -| installationFree | Whether the module supports the installation-free feature.
- **true**: The module supports the installation-free feature and meets installation-free constraints.
- **false**: The module does not support the installation-free feature.
**NOTE**
- If this tag is set to **true** for an entry-type module, it must also be set to **true** for feature-type modules of the same application.
- If this tag is set to **false** for an entry-type module, it can be set to **true** or **false** for feature-type modules of the same application based on service requirements.| Boolean| No| +| installationFree | Whether the module supports the installation-free feature.
- **true**: The module supports the installation-free feature and meets installation-free constraints.
- **false**: The module does not support the installation-free feature.
**NOTE**
If this tag is set to **true** for an entry-type module, it must also be set to **true** for feature-type modules of the same application.
If this tag is set to **false** for an entry-type module, it can be set to **true** or **false** for feature-type modules of the same application based on service requirements.| Boolean| No| | virtualMachine | Type of the target virtual machine (VM) where the module runs. It is used for cloud distribution, such as distribution by the application market and distribution center.
If the target VM type is ArkTS engine, the value is **ark**+*version number*.| String| Yes (initial value: automatically inserted when DevEco Studio builds the HAP file)| | [pages](#pages)| Profile that represents information about each page in the current module. The value can contain a maximum of 255 bytes.| String| No in the UIAbility scenario| | [metadata](#metadata)| Custom metadata of the module. The setting is valid only for the current module, UIAbility, or ExtensionAbility.| Object array| Yes (initial value: left empty)| @@ -87,7 +89,10 @@ As shown above, the **module.json5** file contains several tags. | [extensionAbilities](#extensionabilities) | ExtensionAbility configuration of the module, which is valid only for the current ExtensionAbility component.| Object| Yes (initial value: left empty)| | [requestPermissions](#requestpermissions) | A set of permissions that the application needs to request from the system for running correctly.| Object| Yes (initial value: left empty)| | [testRunner](#testrunner) | Test runner configuration of the module.| Object| Yes (initial value: left empty)| - +| [atomicService](#atomicservice)| Atomic service configuration.| Object| Yes (initial value: left empty) | +| [dependencies](#dependencies)| List of shared libraries on which the current module depends during running.| Object array| Yes (initial value: left empty) | +| targetModuleName | Target module of the bundle. The value is a string with a maximum of 31 bytes. It must be unique in the entire application.|String|Yes (if the initial value is used, the target module is not a module with the overlay feature)| +| targetPriority | Priority of the module. When **targetModuleName** is set, the module is a module with the overlay feature. The value ranges from 1 to 100.|Number|Yes (initial value: **1**)| ## deviceTypes @@ -131,8 +136,21 @@ The **pages** tag is a profile that represents information about specified pages } ``` -Define the **main_pages.json** file under **resources/base/profile** in the development view. The base name of the file (**main_pages** in this example) can be customized, but must be consistent with the information specified by the **pages** tag. The file lists the page information of the current application. +Define the **main_pages.json** file under **resources/base/profile** in the development view. The file name (**main_pages** in this example) can be customized, but must be consistent with the information specified by the **pages** tag. The file lists the page information of the current application, including the route information and the window-related configuration. + + **Table 3** Tags in the pages configuration file +| Name| Description| Data Type| Initial Value Allowed| +| -------- | -------- | -------- | -------- | +| src | Route information about all pages in the JavaScript module, including the page path and page name. The value is an array, each element of which represents a page and the first element represents the home page.| String array| No| +| window | Window-related configuration. | Object| Yes (initial value: left empty)| + + **Table 4** window tag in the pages configuration file + +| Name| Description| Data Type| Initial Value Allowed| +| -------- | -------- | -------- | -------- | +| designWidth | Baseline width for page design. The size of an element is scaled by the actual device width.| Number| Yes (initial value: **720px**)| +| autoDesignWidth | Whether to automatically calculate the baseline width for page design. If it is set to **true**, the **designWidth** attribute becomes invalid. The baseline width is calculated based on the device width and screen density.| Boolean| Yes (initial value: **false**)| ```json { @@ -141,7 +159,11 @@ Define the **main_pages.json** file under **resources/base/profile** in the deve "pages/second/payment", "pages/third/shopping_cart", "pages/four/owner" - ] + ], + "window": { + "designWidth": 720, + "autoDesignWidth": false + } } ``` @@ -150,7 +172,7 @@ Define the **main_pages.json** file under **resources/base/profile** in the deve The **metadata** tag represents the custom metadata of the HAP file. The tag value is an array and contains three subtags: **name**, **value**, and **resource**. -**Table 3** metadata +**Table 5** metadata | Name| Description| Data Type| Initial Value Allowed| | -------- | -------- | -------- | -------- | @@ -165,7 +187,7 @@ The **metadata** tag represents the custom metadata of the HAP file. The tag val "metadata": [{ "name": "module_metadata", "value": "a test demo for module metadata", - "resource": "$profile:shortcuts_config", + "resource": "$profile:shortcuts_config" }], "abilities": [{ @@ -206,10 +228,13 @@ UIAbility configuration of the module, which is valid only for the current UIAbi The OpenHarmony system imposes a strict rule on the presence of application icons. If no icon is configured in the HAP file of an application, the system uses the icon specified in the **app.json** file as the application icon and displays it on the home screen. -Touching this icon will direct the user to the application details screen in **Settings**. +Touching this icon will direct the user to the application details screen in **Settings**, as shown in Figure 1. To hide an application icon from the home screen, you must configure the **AllowAppDesktopIconHide** privilege. For details, see [Application Privilege Configuration Guide](../../device-dev/subsystems/subsys-app-privilege-config-guide.md). +**Objectives**: + +This requirement on application icons is intended to prevent malicious applications from deliberately configuring no icon to block uninstallation attempts. **Setting the application icon to be displayed on the home screen**: @@ -231,40 +256,42 @@ Set **icon**, **label**, and **skills** under **abilities** in the **module.json }] }], ... - + } } ``` -**Querying an application icon:** -* The HAP file contains ability configuration. - * The application icon is set under **abilities** in the **module.json5** file. +**Display rules of application icons and labels on the home screen:** +* The HAP file contains UIAbility configuration. + * The application icon on the home screen is set under **abilities** in the **module.json5** file. * The application does not have the privilege to hide its icon from the home screen. - * The returned home screen icon is the icon configured for the ability. - * The returned home screen label is the label configured for the ability. If no label is configured, the bundle name is returned. - * The returned component name is the component name of the ability. - * When the user touches the home screen icon, the home screen of the ability is displayed. + * The application icon displayed on the home screen is the icon configured for the UIAbility. + * The application label displayed on the home screen is the label configured for the UIAbility. If no label is configured, the bundle name is returned. + * The name of the UIAbility is displayed. + * When the user touches the home screen icon, the home screen of the UIAbility is displayed. * The application has the privilege to hide its icon from the home screen. * The information about the application is not returned during home screen information query, and the icon of the application is not displayed on the home screen. - * The application icon is not set under **abilities** in the **module.json5** file. + * The application icon on the home screen is not set under **abilities** in the **module.json5** file. * The application does not have the privilege to hide its icon from the home screen. - * The returned home screen icon is the icon configured under **app**. (The **icon** parameter in the **app.json** file is mandatory.) - * The returned home screen label is the label configured under **app**. (The **label** parameter in the **app.json** file is mandatory.) - * The returned component name is the component name displayed on the application details screen (this component is built in the system). - * Touching the home screen icon will direct the user to the application details screen. + * The application icon displayed on the home screen is the icon specified under **app**. (The **icon** field in the **app.json** file is mandatory.) + * The application label displayed on the home screen is the label specified under **app**. (The **label** field in the **app.json** file is mandatory.) + * Touching the application icon on the home screen will direct the user to the application details screen shown in Figure 1. * The application has the privilege to hide its icon from the home screen. * The information about the application is not returned during home screen information query, and the icon of the application is not displayed on the home screen. -* The HAP file does not contain ability configuration. +* The HAP file does not contain UIAbility configuration. * The application does not have the privilege to hide its icon from the home screen. - * The returned home screen icon is the icon configured under **app**. (The **icon** parameter in the **app.json** file is mandatory.) - * The returned home screen label is the label configured under **app**. (The **label** parameter in the **app.json** file is mandatory.) - * The returned component name is the component name displayed on the application details screen (this component is built in the system). - * Touching the home screen icon will direct the user to the application details screen. + * The application icon displayed on the home screen is the icon specified under **app**. (The **icon** field in the **app.json** file is mandatory.) + * The application label displayed on the home screen is the label specified under **app**. (The **label** field in the **app.json** file is mandatory.) + * Touching the application icon on the home screen will direct the user to the application details screen shown in Figure 1. * The application has the privilege to hide its icon from the home screen. - * The information about the application is not returned during home screen information query, and the icon of the application is not displayed on the home screen. + * The information about the application is not returned during home screen information query, and the icon of the application is not displayed on the home screen.

+ +**Figure 1** Application details screen +![Application details screen](figures/application_details.jpg) - **Table 4** abilities + + **Table 6** abilities | Name| Description| Data Type| Initial Value Allowed| | -------- | -------- | -------- | -------- | @@ -285,14 +312,14 @@ Set **icon**, **label**, and **skills** under **abilities** in the **module.json | removeMissionAfterTerminate | Whether to remove the relevant task from the task list after the UIAbility component is destroyed.
- **true**: Remove the relevant task from the task list after the UIAbility component is destroyed.
- **false**: Do not remove the relevant task from the task list after the UIAbility component is destroyed.| Boolean| Yes (initial value: **false**)| | orientation | Orientation of the UIAbility component when it is started. The options are as follows:
- **unspecified**: automatically determined by the system.
- **landscape**: landscape mode.
- **portrait**: portrait mode.
- **landscape_inverted**: inverted landscape mode.
- **portrait_inverted**: inverted portrait mode.
- **auto_rotation**: determined by the sensor.
- **auto_rotation_landscape**: determined by the sensor in the horizontal direction, including landscape and inverted landscape modes.
- **auto_rotation_portrait**: determined by the sensor in the vertical direction, including portrait and inverted portrait modes.
- **auto_rotation_restricted**: determined by the sensor when the sensor switch is enabled.
- **auto_rotation_landscape_restricted**: determined by the sensor in the horizontal direction, including landscape and inverted landscape modes, when the sensor switch is enabled.
- **auto_rotation_portrait_restricted**: determined by the sensor in the vertical direction, including portrait and inverted portrait modes, when the sensor switch is enabled.
- **locked**: auto rotation disabled.| String| Yes (initial value: **"unspecified"**)| | supportWindowMode | Window mode supported by the UIAbility component. The options are as follows:
- **fullscreen**: full-screen mode.
- **split**: split-screen mode.
- **floating**: floating window mode.| String array| Yes (initial value:
["fullscreen", "split", "floating"])| -| priority | Priority of the UIAbility component. In the case of [implicit query](../application-models/explicit-implicit-want-mappings.md), UIAbility components with a higher priority are at the higher place of the returned list. The value is an integer ranging from 0 to 10. The greater the value, the higher the priority.
**NOTE**
This tag applies only to system applications and does not take effect for third-party applications.| Number| Yes (initial value: **0**)| +| priority | Priority of the UIAbility component. In the case of [implicit query](../application-models/explicit-implicit-want-mappings.md), UIAbility components with a higher priority are at the higher place of the returned list. The value is an integer ranging from 0 to 10. The greater the value, the higher the priority.
**NOTE**
This attribute applies only to system applications and does not take effect for third-party applications.| Number| Yes (initial value: **0**)| | maxWindowRatio | Maximum aspect ratio supported by the UIAbility component. The minimum value is 0.| Number| Yes (initial value: maximum aspect ratio supported by the platform)| | minWindowRatio | Minimum aspect ratio supported by the UIAbility component. The minimum value is 0.| Number| Yes (initial value: minimum aspect ratio supported by the platform)| | maxWindowWidth | Maximum window width supported by the UIAbility component, in vp. The minimum value is 0, and the value cannot be less than the value of **minWindowWidth** or greater than the maximum window width allowed by the platform. For details about the window size, see [Constraints](../windowmanager/window-overview.md#constraints).| Number| Yes (initial value: maximum window width supported by the platform)| | minWindowWidth | Minimum window width supported by the UIAbility component, in vp. The minimum value is 0, and the value cannot be less than the minimum window width allowed by the platform or greater than the value of **maxWindowWidth**. For details about the window size, see [Constraints](../windowmanager/window-overview.md#constraints).| Number| Yes (initial value: minimum window width supported by the platform)| | maxWindowHeight | Maximum window height supported by the UIAbility component, in vp. The minimum value is 0, and the value cannot be less than the value of **minWindowHeight** or greater than the maximum window height allowed by the platform. For details about the window size, see [Constraints](../windowmanager/window-overview.md#constraints).| Number| Yes (initial value: maximum window height supported by the platform)| | minWindowHeight | Minimum window height supported by the UIAbility component, in vp. The minimum value is 0, and the value cannot be less than the minimum window height allowed by the platform or greater than the value of **maxWindowHeight**. For details about the window size, see [Constraints](../windowmanager/window-overview.md#constraints).| Number| Yes (initial value: minimum window height supported by the platform)| -| excludeFromMissions | Whether the UIAbility component is displayed in the recent task list.
- **true**: displayed in the recent task list.
- **false**: not displayed in the recent task list.
**NOTE**
This tag applies only to system applications and does not take effect for third-party applications.| Boolean| Yes (initial value: **false**)| +| excludeFromMissions | Whether the UIAbility component is displayed in the recent task list.
- **true**: displayed in the recent task list.
- **false**: not displayed in the recent task list.
**NOTE**
This attribute applies only to system applications and does not take effect for third-party applications.| Boolean| Yes (initial value: **false**)| | recoverable | Whether the application can be recovered to its previous state in case of a detected fault.
- **true**: The application can be recovered to its previous state in case of a detected fault.
- **false**: The application cannot be recovered to its previous state in case of a detected fault.| Boolean| Yes (initial value: **false**)| Example of the **abilities** structure: @@ -348,7 +375,7 @@ Example of the **abilities** structure: The **skills** tag represents the feature set of [wants](../application-models/want-overview.md) that can be received by the UIAbility or ExtensionAbility component. - **Table 5** skills + **Table 7** skills | Name| Description| Data Type| Initial Value Allowed| | -------- | -------- | -------- | -------- | @@ -356,7 +383,7 @@ The **skills** tag represents the feature set of [wants](../application-models/w | entities | [Entities](../application-models/actions-entities.md) of wants that can be received.| String array| Yes (initial value: left empty)| |uris | URIs that match the wants.| Object array| Yes (initial value: left empty)| - **Table 6** uris + **Table 8** Internal structure of the uris tag | Name| Description| Data Type| Initial Value Allowed| | -------- | -------- | -------- | -------- | @@ -397,44 +424,11 @@ Example of the **skills** structure: } ``` -**Enhanced implicit query** - -URI-level prefix matching is supported. -When only **scheme** or a combination of **scheme** and **host** or **scheme**, **host**, and **port** are configured in the configuration file, the configuration is successful if a URI prefixed with the configuration file is passed in. - - - * The query enhancement involves the following APIs: - [@ohos.bundle.bundleManager](../reference/apis/js-apis-bundleManager.md#bundlemanagerqueryabilityinfo)
- 1. function queryAbilityInfo(want: Want, abilityFlags: number, callback: AsyncCallback>): void;
- 2. function queryAbilityInfo(want: Want, abilityFlags: number, userId: number, callback: AsyncCallback>): void;
- 3. function queryAbilityInfo(want: Want, abilityFlags: number, userId?: number): Promise>; - * Configuration requirements
- abilities -> skills -> uris object
- Configuration 1: only **scheme = 'http'**
- Configuration 2: only **(scheme = 'http') + (host = 'example.com')**
- Configuration 3: only **(scheme = 'http') + (host = 'example.com') + (port = '8080')** - * Prefix match
- If the value of **uri** under [want](../application-models/want-overview.md) is obtained by calling the **queryAbilityInfo** API: - 1. uri = 'https://': No matches
- 2. uri = 'http://': Matches configuration 1
- 3. uri = 'https://example.com': No matches
- 4. uri = 'https://exa.com': No matches
- 5. uri = 'http://exa.com': Matches configuration 1
- 6. uri = 'http://example.com': Matches configuration 1 and configuration 2
- 7. uri = 'https://example.com:8080': No matches
- 8. uri = 'http://exampleaa.com:8080': Matches configuration 1
- 9. uri = 'http://example.com:9180': Matches configuration 1 and configuration 2
- 10. uri = 'http://example.com:8080': Matches configuration 1, configuration 2, and configuration 3
- 11. uri = 'https://example.com:9180/path': No matches
- 12. uri = 'http://exampleap.com:8080/path': Matches configuration 1
- 13. uri = 'http://example.com:9180/path': Matches configuration 1 and configuration 2
- 14. uri = 'http://example.com:8080/path': Matches configuration 1, configuration 2, and configuration 3
- ## extensionAbilities The **extensionAbilities** tag represents the configuration of extensionAbilities, which is valid only for the current extensionAbility. - **Table 7** extensionAbilities + **Table 9** extensionAbilities | Name| Description| Data Type| Initial Value Allowed| | -------- | -------- | -------- | -------- | @@ -443,10 +437,10 @@ The **extensionAbilities** tag represents the configuration of extensionAbilitie | description | Description of the ExtensionAbility component. The value is a string with a maximum of 255 bytes or a resource index to the description.| String| Yes (initial value: left empty)| | icon | Icon of the ExtensionAbility component. The value is an icon resource index. If **ExtensionAbility** is set to **MainElement** of the current module, this attribute is mandatory and its value must be unique in the application.| String| Yes (initial value: left empty)| | label | Name of the ExtensionAbility component displayed to users. The value is a string resource index.
**NOTE**
If **ExtensionAbility** is set to **MainElement** of the current module, this attribute is mandatory and its value must be unique in the application.| String| No| -| type | Type of the ExtensionAbility component. The options are as follows:
- **form**: ExtensionAbility of a widget.
- **workScheduler**: ExtensionAbility of a Work Scheduler task.
- **inputMethod**: ExtensionAbility of an input method.
- **service**: service component running in the background.
- **accessibility**: ExtensionAbility of an accessibility feature.
- **dataShare**: ExtensionAbility for data sharing.
- **fileShare**: ExtensionAbility for file sharing.
- **staticSubscriber**: ExtensionAbility for static broadcast.
- **wallpaper**: ExtensionAbility of the wallpaper.
- **backup**: ExtensionAbility for data backup.
- **window**: ExtensionAbility of a window. This type of ExtensionAbility creates a window during startup for which you can develop the GUI. The window is then combined with other application windows through **abilityComponent**.
- **thumbnail**: ExtensionAbility for obtaining file thumbnails. You can provide thumbnails for files of customized file types.
- **preview**: ExtensionAbility for preview. This type of ExtensionAbility can parse the file and display it in a window. You can combine the window with other application windows.
- **print**: ExtensionAbility for the print framework.
**NOTE**
The **service** and **dataShare** types apply only to system applications and do not take effect for third-party applications.| String| No| +| type | Type of the ExtensionAbility component. The options are as follows:
- **form**: ExtensionAbility of a widget.
- **workScheduler**: ExtensionAbility of a Work Scheduler task.
- **inputMethod**: ExtensionAbility of an input method.
- **service**: service component running in the background.
- **accessibility**: ExtensionAbility of an accessibility feature.
- **dataShare**: ExtensionAbility for data sharing.
- **fileShare**: ExtensionAbility for file sharing.
- **staticSubscriber**: ExtensionAbility for static broadcast.
- **wallpaper**: ExtensionAbility of the wallpaper.
- **backup**: ExtensionAbility for data backup.
- **window**: ExtensionAbility of a window. This type of ExtensionAbility creates a window during startup for which you can develop the GUI. The window is then combined with other application windows through **abilityComponent**.
- **thumbnail**: ExtensionAbility for obtaining file thumbnails. You can provide thumbnails for files of customized file types.
- **preview**: ExtensionAbility for preview. This type of ExtensionAbility can parse the file and display it in a window. You can combine the window with other application windows.
- **print**: ExtensionAbility for the print framework.
- **driver**: ExtensionAbility for the driver framework.
**NOTE**
The **service** and **dataShare** types apply only to system applications and do not take effect for third-party applications.| String| No| | permissions | Permissions required for another application to access the ExtensionAbility component.
The value is generally in the reverse domain name notation and contains a maximum of 255 bytes. It is an array of permission names predefined by the system or customized. The name of a customized permission must be the same as the **name** value of a permission defined in the **defPermissions** attribute.| String array| Yes (initial value: left empty)| -| uri | Data URI provided by the ExtensionAbility component. The value is a string with a maximum of 255 bytes, in the reverse domain name notation.
**NOTE**
This attribute is mandatory when the type of the **ExtensionAbility** component is set to **dataShare**. | String| Yes (initial value: left empty)| -|skills | Feature set of [wants](../application-models/want-overview.md) that can be received by the ExtensionAbility component.
Configuration rule: In an entry package, you can configure multiple **skills** attributes with the entry capability. (A **skills** attribute with the entry capability is the one that has **ohos.want.action.home** and **entity.system.home** configured.) The **label** and **icon** in the first ExtensionAbility that has **skills** configured are used as the **label** and **icon** of the entire OpenHarmony service/application.
**NOTE**
The **skills** attribute with the entry capability can be configured for the feature-type package of an OpenHarmony application, but not for an OpenHarmony service. | Array| Yes (initial value: left empty)| +| uri | Data URI provided by the ExtensionAbility component. The value is a string with a maximum of 255 bytes, in the reverse domain name notation.
**NOTE**
This attribute is mandatory when the type of the ExtensionAbility component is set to **dataShare**.| String| Yes (initial value: left empty)| +|skills | Feature set of [wants](../application-models/want-overview.md) that can be received by the ExtensionAbility component.
Configuration rule: In an entry package, you can configure multiple **skills** attributes with the entry capability. (A **skills** attribute with the entry capability is the one that has **ohos.want.action.home** and **entity.system.home** configured.) The **label** and **icon** in the first ExtensionAbility that has **skills** configured are used as the **label** and **icon** of the entire OpenHarmony service/application.
**NOTE**
The **skills** attribute with the entry capability can be configured for the feature package of an OpenHarmony application, but not for an OpenHarmony service. | Array| Yes (initial value: left empty)| | [metadata](#metadata)| Metadata of the ExtensionAbility component.| Object| Yes (initial value: left empty)| | exported | Whether the ExtensionAbility component can be called by other applications.
- **true**: The ExtensionAbility component can be called by other applications.
- **false**: The UIAbility component cannot be called by other applications.| Boolean| Yes (initial value: **false**)| @@ -462,7 +456,7 @@ Example of the **extensionAbilities** structure: "icon": "$media:icon", "label" : "$string:extension_name", "description": "$string:form_description", - "type": "form", + "type": "form", "permissions": ["ohos.abilitydemo.permission.PROVIDER"], "readPermission": "", "writePermission": "", @@ -476,7 +470,7 @@ Example of the **extensionAbilities** structure: "metadata": [ { "name": "ohos.extension.form", - "resource": "$profile:form_config", + "resource": "$profile:form_config", } ] } @@ -494,12 +488,12 @@ The **requestPermissions** tag represents a set of permissions that the applicat > - The permission settings configured in the **requestPermissions** tag apply to the entire application. > - If your application needs to subscribe to an event published by itself and the permissions required for accessing the application are set in the **permissions** tag under **extensionAbilities**, then the application must register the related permissions in the **requestPermissions** tag to receive the event. -**Table 8** requestPermissions +**Table 10** requestPermissions | Name| Description| Data Type| Value Range| Default Value| | -------- | -------- | -------- | -------- | -------- | | name | Permission name. This attribute is mandatory.| String| Custom| –| -| reason | Reason for requesting the permission. This attribute is mandatory when the permission to request is **user_grant**.
**NOTE**
If the permission to request is **user_grant**, this attribute is required for the application to be released to the application market, and multi-language adaptation is required.| String| Resource reference of the string type in $string: \*\*\* format| A null value| +| reason | Reason for requesting the permission. This attribute is mandatory when the permission to request is **user_grant**.
**NOTE**
If the permission to request is **user_grant**, this attribute is required for the application to be released to the application market. Multi-language adaptation is required.| String| Resource reference of the string type in $string: \*\*\* format| A null value| | usedScene | Scene under which the permission is used. It consists of the **abilities** and **when** sub-attributes. Multiple abilities can be configured.
**NOTE**
This attribute is optional by default. If the permission to request is **user_grant**, the **abilities** sub-attribute is mandatory and **when** is optional.| **abilities**: string array
**when**: string| **abilities**: array of names of UIAbility or ExtensionAbility components
**when**: **inuse** or **always**| **abilities**: null
**when**: null| Example of the **requestPermissions** structure: @@ -534,8 +528,10 @@ The **shortcut** information is identified in **metadata**, where: - **name** indicates the name of the shortcut, identified by **ohos.ability.shortcuts**. - **resource** indicates where the resources of the shortcut are stored. - -| Attribute| Description| Data Type | Default Value| + +**Table 11** shortcuts + +| Name| Description| Data Type | Default Value| | -------- | -------- | -------- | -------- | | shortcutId | ID of the shortcut. The value is a string with a maximum of 63 bytes.| String| No| | label | Label of the shortcut, that is, the text description displayed for the shortcut. The value can be a string or a resource index to the label, with a maximum of 255 bytes.| String| Yes (initial value: left empty)| @@ -544,7 +540,7 @@ The **shortcut** information is identified in **metadata**, where: 1. Configure the **shortcuts_config.json** file in **/resource/base/profile/**. - + ```json { "shortcuts": [ @@ -564,7 +560,7 @@ The **shortcut** information is identified in **metadata**, where: ``` 2. In the **abilities** tag of the **module.json5** file, configure the **metadata** tag for the UIAbility component to which a shortcut needs to be added so that the shortcut configuration file takes effect for the UIAbility. - + ```json { "module": { @@ -601,7 +597,7 @@ The **shortcut** information is identified in **metadata**, where: The **distributionFilter** tag defines the rules for distributing HAP files based on different device specifications, so that precise matching can be performed when the application market distributes applications. Distribution rules cover five factors: API version, screen shape, screen size, screen resolution, and country code. During distribution, a unique HAP is determined based on the mapping between **deviceType** and these five factors. This tag must be configured in the **/resource/profile resource** directory. Its sub-tags are optional. - **Table 9** distributionFilter + **Table 12** distributionFilter | Name| Description| Data Type| Initial Value Allowed| | -------- | -------- | -------- | -------- | @@ -611,28 +607,28 @@ The **distributionFilter** tag defines the rules for distributing HAP files base | countryCode | Code of the country or region to which the application is to be distributed. The value is subject to the ISO-3166-1 standard. Enumerated definitions of multiple countries and regions are supported.| Object array| Yes (initial value: left empty)| - **Table 10** screenShape + **Table 13** Internal structure of the screenShape tag | Name| Description| Data Type| Initial Value Allowed| | -------- | -------- | -------- | -------- | | policy | Rule for the sub-attribute value. Set this attribute to **exclude** or **include**.
- **exclude**: Exclude the matches of the sub-attribute value.
- **include**: Include the matches of the sub-attribute value.| String| No| | value | Screen shapes. The value can be **circle**, **rect**, or both. Example: Different HAP files can be provided for a smart watch with a circular face and that with a rectangular face.| String array| No| - **Table 11** screenWindow + **Table 14** Internal structure of the screenWindow tag | Name| Description| Data Type| Initial Value Allowed| | -------- | -------- | -------- | -------- | | policy | Rule for the sub-attribute value. Set this attribute to **exclude** or **include**.
- **exclude**: Exclude the matches of the sub-attribute value.
- **include**: Include the matches of the sub-attribute value.| String| No| | value | Screen width and height, in pixels. The value an array of supported width and height pairs, each in the "width * height" format, for example, **"454 * 454"**.| String array| No| - **Table 12** screenDensity + **Table 15** Internal structure of the screenDensity tag | Name| Description| Data Type| Initial Value Allowed| | -------- | -------- | -------- | -------- | | policy | Rule for the sub-attribute value. Set this attribute to **exclude** or **include**.
- **exclude**: Exclude the matches of the sub-attribute value.
- **include**: Include the matches of the sub-attribute value.| String| No| | value | Pixel density of the screen, in DPI.| String array| No| - **Table 13** countryCode + **Table 16** Internal structure of the countryCode tag | Name| Description| Data Type| Initial Value Allowed| | -------- | -------- | -------- | -------- | @@ -699,14 +695,14 @@ Configure **metadata** in the **module** tag in the **module.json5** file. The **testRunner** tag represents the supported test runner. -**Table 14** testRunner +**Table 17** Internal structure of the testRunner tag | Name| Description| Data Type| Initial Value Allowed| | -------- | -------- | -------- | -------- | | name | Name of the test runner object. The value is a string with a maximum of 255 bytes.| String| No| | srcPath | Code path of the test runner. The value is a string with a maximum of 255 bytes.| String| No| -Example of the / structure: +Example of the **testRunner** structure: ```json @@ -720,3 +716,84 @@ Example of the / structure: } } ``` + +## atomicService + +The **atomicService** tag represents the atomic service configuration. It is available only when **bundleType** is set to **atomicService** in the **app.json** file. + +**Table 18** Internal structure of the atomicService tag + +| Name| Description| Data Type| Initial Value Allowed| +| -------- | -------- | -------- | -------- | +| preloads | List of modules to pre-load.| Object array| Yes (initial value: left empty)| + +Example of the **atomicService** structure: + + +```json +{ + "module": { + "atomicService": { + "preloads":[ + { + "moduleName":"feature" + } + ] + } + } +} +``` + +## preloads + +The **preloads** tag represents a list of modules to pre-load in an atomic service. + +**Table 19** Internal structure of the preloads tag + +| Name| Description| Data Type| Initial Value Allowed| +| -------- | -------- | -------- | -------- | +| moduleName | Name of the module to be preloaded when the current module is loaded in the atomic service.| String| No| + +Example of the **preloads** structure: + +```json +{ + "module": { + "atomicService": { + "preloads":[ + { + "moduleName":"feature" + } + ] + } + } +} +``` + +## dependencies + +The **dependencies** tag identifies the list of shared libraries that the module depends on when it is running. + +**Table 20** Internal structure of the dependencies tag + +| Name | Description | Data Type| Initial Value Allowed| +| ----------- | ------------------------------ | -------- | ---------- | +| bundleName | Name of the shared bundle on which the current module depends. | String | Yes| +| moduleName | Module name of the shared bundle on which the current module depends.| String | No| +| versionCode | Version number of the shared bundle. | Number | Yes| + +Example of the **dependencies** structure: + +```json +{ + "module": { + "dependencies": [ + { + "bundleName":"com.share.library", + "moduleName": "library", + "versionCode": 10001 + } + ] + } +} +``` diff --git a/en/application-dev/quick-start/module-structure.md b/en/application-dev/quick-start/module-structure.md index 352a993d50..d4593c1274 100644 --- a/en/application-dev/quick-start/module-structure.md +++ b/en/application-dev/quick-start/module-structure.md @@ -192,12 +192,20 @@ Example of the metadata attribute: **By default, application icons cannot be hidden from the home screen in OpenHarmony.** -The OpenHarmony system imposes a strict rule on the presence of application icons. If no icon is configured in the HAP file of an application, the system creates a default icon for the application and displays it on the home screen.
-Touching this icon will direct the user to the application details screen in **Settings**. +The OpenHarmony system imposes a strict rule on the presence of application icons. If no icon is configured in the HAP file of an application, the system creates a default icon for the application and displays it on the home screen. + +Touching this icon will direct the user to the application details screen in **Settings**, as shown in Figure 1. + To hide an application icon from the home screen, you must configure the **AllowAppDesktopIconHide** privilege. For details, see [Application Privilege Configuration Guide](../../device-dev/subsystems/subsys-app-privilege-config-guide.md). +**Objectives**: + +This requirement on application icons is intended to prevent malicious applications from deliberately configuring no icon to block uninstallation attempts. + +**Setting the application icon to be displayed on the home screen**: + +Set **icon**, **label**, and **skills** under **abilities** in the **config.json** file. In addition, make sure the **skills** configuration contains **ohos.want.action.home** and **entity.system.home**. -**Setting the application icon to be displayed on the home screen**:
Set **icon**, **label**, and **skills** under **abilities** in the **config.json** file. In addition, make sure the **skills** configuration contains **ohos.want.action.home** and **entity.system.home**. ``` { "module":{ @@ -220,36 +228,37 @@ To hide an application icon from the home screen, you must configure the **Allow } ``` -**Querying an application icon:** +**Display rules of application icons and labels on the home screen:** * The HAP file contains Page ability configuration. - * The application icon is set under **abilities** in the **config.json** file. + * The application icon on the home screen is set under **abilities** in the **config.json** file. * The application does not have the privilege to hide its icon from the home screen. - * The returned home screen icon is the icon configured for the ability. - * The returned home screen label is the label configured for the ability. If no label is configured, the bundle name is returned. - * The returned component name is the component name of the ability. - * When the user touches the home screen icon, the home screen of the ability is displayed. + * The application icon displayed on the home screen is the icon configured for the Page ability. + * The application label displayed on the home screen is the label configured for the Page ability. If no label is configured, the bundle name is returned. + * The name of the Page ability is displayed. + * When the user touches the home screen icon, the home screen of the Page ability is displayed. * The application has the privilege to hide its icon from the home screen. * The information about the application is not returned during home screen information query, and the icon of the application is not displayed on the home screen. - * The application icon is not set under **abilities** in the **config.json** file. + * The application icon on the home screen is not set under **abilities** in the **config.json** file. * The application does not have the privilege to hide its icon from the home screen. - * The returned home screen icon is the default icon. - *The returned home screen label is the bundle name of the application. - * The returned component name is the component name displayed on the application details screen (this component is built in the system). - * Touching the home screen icon will direct the user to the application details screen. + * The application icon displayed on the home screen is the default icon. + * The application label displayed on the home screen is the bundle name of the application. + * Touching the application icon on the home screen will direct the user to the application details screen shown in Figure 1. * The application has the privilege to hide its icon from the home screen. * The information about the application is not returned during home screen information query, and the icon of the application is not displayed on the home screen. * The HAP file does not contain Page ability configuration. * The application does not have the privilege to hide its icon from the home screen. - * The returned home screen icon is the default icon. - *The returned home screen label is the bundle name of the application. - * The returned component name is the component name displayed on the application details screen (this component is built in the system). - * Touching the home screen icon will direct the user to the application details screen. + * The application icon displayed on the home screen is the default icon. + * The application label displayed on the home screen is the bundle name of the application. + * Touching the application icon on the home screen will direct the user to the application details screen shown in Figure 1. * The application has the privilege to hide its icon from the home screen. * The information about the application is not returned during home screen information query, and the icon of the application is not displayed on the home screen. -> **NOTE** -> -> The icon and label displayed on the application details page may be different from those displayed on the home screen. For non-Page abilities, they are the entry icon and label set under **abilities**, if any. +Note: The label displayed on the application details screen may be different from that displayed on the home screen. For non-Page abilities, it is the entry label set (if any).

+ +**Figure 1** Application details screen + +![Application details screen](figures/application_details.jpg) + **Table 8** Internal structure of the abilities attribute @@ -412,39 +421,6 @@ Example of the **skills** attribute structure: ] ``` -**Enhanced implicit query** - -URI-level prefix matching is supported. - -When only **scheme** or a combination of **scheme** and **host** or **scheme**, **host**, and **port** are configured in the configuration file, the configuration is successful if a URI prefixed with the configuration file is passed in. - - * The query enhancement involves the following APIs:
- [@ohos.bundle.bundleManager](../reference/apis/js-apis-bundleManager.md#bundlemanagerqueryabilityinfo)
- 1. function queryAbilityInfo(want: Want, abilityFlags: number, callback: AsyncCallback>): void;
- 2. function queryAbilityInfo(want: Want, abilityFlags: number, userId: number, callback: AsyncCallback>): void;
- 3. function queryAbilityInfo(want: Want, abilityFlags: number, userId?: number): Promise>; - * Configuration requirements
- abilities -> skills -> uris object
- Configuration 1: only **scheme = 'http'** - Configuration 2: only **(scheme = 'http') + (host = 'www.example.com')** - Configuration 3: only **(scheme = 'http') + (host = 'www.example.com') + (port = '8080')** - * Prefix match
- If the value of **uri** under [want](../application-models/want-overview.md) is obtained by calling the **queryAbilityInfo** API:
- 1. uri = 'https://': No matches
- 2. uri = 'http://': Matches configuration 1
- 3. uri = 'https://www.example.com': No matches
- 4. uri = 'https://www.exa.com': No matches
- 5. uri = 'http://www.exa.com': Matches configuration 1
- 6. uri = 'http://www.example.com': Matches configuration 1 and configuration 2
- 7. uri = 'https://www.example.com:8080': No matches
- 8. uri = 'http://www.exampleaa.com:8080': Matches configuration 1
- 9. uri = 'http://www.example.com:9180': Matches configuration 1 and configuration 2
- 10. uri = 'http://www.example.com:8080': Matches configuration 1, configuration 2, and configuration 3
- 11. uri = 'https://www.example.com:9180/query/student/name' : No matches
- 12. uri = 'http://www.exampleap.com:8080/query/student/name': Matches configuration 1
- 13. uri = 'http://www.example.com:9180/query/student/name': Matches configuration 1 and configuration 2
- 14. uri = 'http://www.example.com:8080/query/student/name': Matches configuration 1, configuration 2, and configuration 3
- ## Internal Structure of the reqPermissions Attribute **Table 12** Internal structure of the reqPermissions attribute diff --git a/en/application-dev/quick-start/multi-hap-objective.md b/en/application-dev/quick-start/multi-hap-objective.md index ad43c84fd7..ae7bb791b7 100644 --- a/en/application-dev/quick-start/multi-hap-objective.md +++ b/en/application-dev/quick-start/multi-hap-objective.md @@ -1,10 +1,10 @@ # Multi-HAP Design Objectives -- Modular management: A well-designed application is generally managed in a modular manner, where modules are loosely coupled. In light of this, the multi-HAP mechanism is designed, allowing you to divide services into multiple modules and store each module in an independent HAP file. For example, If you are developing a payment application and its home screen consists of multiple modules, such as the scan, pay, messaging, and finance modules, you can implement the logic of the home screen for managing other modules in the entry-type HAP file, and implement specific modules in feature-type HAP files. The feature-type HAP files are independent. You can develop and test each of them separately, and then integrate them with the entry-type HAP file. +- Modular management: A well-designed application is generally managed in a modular manner, where modules are loosely coupled. In light of this, the multi-HAP mechanism is designed, allowing you to divide services into multiple modules and store each module in an independent HAP file. For example, if you are developing a payment application whose home screen consists of multiple modules, such as the scan, pay, messaging, and finance modules, you can implement the HAP files as follows: (1) In the entry-type HAP file, implement the home screen logic for managing modules; (2) in feature-type HAP files, implement specific modules. The feature-type HAP files are independent of each other. You can develop and test each of them separately, and then integrate them with the entry-type HAP file. -- Flexible deployment: You can combine multiple HAP files and deploy them on different devices. Assume that an application contains one entry-type HAP file (**Entry.hap**) and two feature-type HAP files (**Feature1.hap** and **Feature2.hap**). The **Entry.hap** file can be deployed on device A and device B, the **Feature1.hap** file can be deployed only on device A, and the **Feature2.hap** can be deployed only on device B. In this way, you can easily combine the **Entry.hap** and **Feature1.hap** files and deploy them on device A, and combine the **Entry.hap** and **Feature2.hap** files and deploy them on device B. +- Flexible deployment: You can flexibly combine HAP files for device-specific deployment. Assume that an application contains one entry-type HAP file (**entry.hap**) and two feature-type HAP files (**Feature1.hap** and **Feature2.hap**). The **Entry.hap** file can be deployed on device A and device B, the **Feature1.hap** file can be deployed only on device A, and the **Feature2.hap** can be deployed only on device B. This means that you can combine the **Entry.hap** and **Feature1.hap** files and deploy them on device A, and combine the **Entry.hap** and **Feature2.hap** files and deploy them on device B. -- On-demand loading: You can load modules only when they are needed, reducing the package size. Specifically, you can configure some HAP files of an application to be loaded on demand. For example, if some features are not used during application startup, you can configure them to be loaded only when they are needed, rather than being loaded at startup. This can reduce the size of the application package to some extent. +- On-demand loading: You can load modules only when they are needed, reducing the package size. Specifically, you can configure some HAP files of your application to be loaded on demand. For example, if some features are not used during application startup, you can configure them to be loaded only when they are needed, rather than being loaded at startup. This can reduce the size of the application package to some extent. -- Easier resource sharing: The resources (including public resource files and public pages) and shared objects (.so library files) required by multiple HAP files can be stored in an independent HAP file. In this way, other HAP files can obtain the resources and files by accessing the HAP, which reduces the size of the application package to some extent. +- Easier resource sharing: The resources (including public resource files and public pages) and shared objects (.so library files) required by multiple HAP files can be stored in an independent HAP file. In this way, other HAP files can obtain the resources and files by accessing the HAP, which also reduces the size of the application package to some extent. -- GitLab