“4505dd4f2bd8c0d7f97ed463ae45b9ce2ea22bc1”上不存在“...native/git@gitcode.net:openanolis/dragonwell8_jdk.git”
提交 f78c457f 编写于 作者: H HelloCrease

Merge branch 'OpenHarmony-4.0-Beta1' of https://gitee.com/HelloCrease/docs...

Merge branch 'OpenHarmony-4.0-Beta1' of https://gitee.com/HelloCrease/docs into OpenHarmony-4.0-Beta1
# OpenHarmony Project # OpenHarmony Project
> **NOTE**
>
> You are reading documents of OpenHarmony 4.0 Beta1. Obtain the [compatible SDK](release-notes/OpenHarmony-v4.0-beta1.md#version-mapping) during your application development.
## Introduction ## Introduction
OpenHarmony is an open-source project incubated and operated by the OpenAtom Foundation. The purpose of this project is to build an open-source, distributed operating system (OS) framework for smart devices in all scenarios of a fully-connected world. OpenHarmony is an open-source project incubated and operated by the OpenAtom Foundation. The purpose of this project is to build an open-source, distributed operating system (OS) framework for smart devices in all scenarios of a fully-connected world.
......
# Application Development Overview # Application Development Overview
> **NOTE**
>
> You are reading documents of OpenHarmony 4.0 Beta1. Obtain the [compatible SDK](../release-notes/OpenHarmony-v4.0-beta1.md#version-mapping) during your application development.
The application development documents provide reference for you to develop applications using the APIs provided by OpenHarmony. They walk you through how to use JavaScript APIs to develop applications on the standard system. The application development documents provide reference for you to develop applications using the APIs provided by OpenHarmony. They walk you through how to use JavaScript APIs to develop applications on the standard system.
The documents are carefully organized as follows: The documents are carefully organized as follows:
......
...@@ -8,14 +8,14 @@ ...@@ -8,14 +8,14 @@
- Stage Mode Application Components - Stage Mode Application Components
- [Application- or Component-Level Configuration](application-component-configuration-stage.md) - [Application- or Component-Level Configuration](application-component-configuration-stage.md)
- UIAbility Component - UIAbility Component
- [UIAbility Component Overview](uiability-overview.md) - [UIAbility Overview](uiability-overview.md)
- [UIAbility Component Lifecycle](uiability-lifecycle.md) - [UIAbility Lifecycle](uiability-lifecycle.md)
- [UIAbility Component Launch Type](uiability-launch-type.md) - [UIAbility Launch Type](uiability-launch-type.md)
- [UIAbility Component Usage](uiability-usage.md) - [UIAbility Usage](uiability-usage.md)
- [Data Synchronization Between UIAbility and UI](uiability-data-sync-with-ui.md) - [Data Synchronization Between UIAbility and UI Page](uiability-data-sync-with-ui.md)
- [Interaction Between Intra-Device UIAbility Components](uiability-intra-device-interaction.md) - [Interaction Between Intra-Device UIAbility Components](uiability-intra-device-interaction.md)
- ExtensionAbility Component - ExtensionAbility Component
- [ExtensionAbility Component Overview](extensionability-overview.md) - [ExtensionAbility Overview](extensionability-overview.md)
- [ServiceExtensionAbility](serviceextensionability.md) - [ServiceExtensionAbility](serviceextensionability.md)
- [AccessibilityExtensionAbility](accessibilityextensionability.md) - [AccessibilityExtensionAbility](accessibilityextensionability.md)
- [EnterpriseAdminExtensionAbility](enterprise-extensionAbility.md) - [EnterpriseAdminExtensionAbility](enterprise-extensionAbility.md)
...@@ -89,8 +89,8 @@ ...@@ -89,8 +89,8 @@
- FA Mode Application Components - FA Mode Application Components
- [Application- or Component-Level Configuration](application-component-configuration-fa.md) - [Application- or Component-Level Configuration](application-component-configuration-fa.md)
- PageAbility Component Development - PageAbility Component Development
- [PageAbility Component Overview](pageability-overview.md) - [PageAbility Overview](pageability-overview.md)
- [PageAbility Component Configuration](pageability-configuration.md) - [PageAbility Configuration](pageability-configuration.md)
- [PageAbility Lifecycle](pageability-lifecycle.md) - [PageAbility Lifecycle](pageability-lifecycle.md)
- [PageAbility Launch Type](pageability-launch-type.md) - [PageAbility Launch Type](pageability-launch-type.md)
- [Creating a PageAbility](create-pageability.md) - [Creating a PageAbility](create-pageability.md)
...@@ -102,15 +102,15 @@ ...@@ -102,15 +102,15 @@
- [Requesting Permissions](request-permissions.md) - [Requesting Permissions](request-permissions.md)
- [Redirection Rules](redirection-rules.md) - [Redirection Rules](redirection-rules.md)
- ServiceAbility Component Development - ServiceAbility Component Development
- [ServiceAbility Component Overview](serviceability-overview.md) - [ServiceAbility Overview](serviceability-overview.md)
- [ServiceAbility Component Configuration](serviceability-configuration.md) - [ServiceAbility Configuration](serviceability-configuration.md)
- [ServiceAbility Lifecycle](serviceability-lifecycle.md) - [ServiceAbility Lifecycle](serviceability-lifecycle.md)
- [Creating a ServiceAbility](create-serviceability.md) - [Creating a ServiceAbility](create-serviceability.md)
- [Starting a ServiceAbility](start-serviceability.md) - [Starting a ServiceAbility](start-serviceability.md)
- [Connecting to a ServiceAbility](connect-serviceability.md) - [Connecting to a ServiceAbility](connect-serviceability.md)
- DataAbility Component Development - DataAbility Component Development
- [DataAbility Component Overview](dataability-overview.md) - [DataAbility Overview](dataability-overview.md)
- [DataAbility Component Configuration](dataability-configuration.md) - [DataAbility Configuration](dataability-configuration.md)
- [DataAbility Lifecycle](dataability-lifecycle.md) - [DataAbility Lifecycle](dataability-lifecycle.md)
- [Creating a DataAbility](create-dataability.md) - [Creating a DataAbility](create-dataability.md)
- [Starting a DataAbility](start-dataability.md) - [Starting a DataAbility](start-dataability.md)
......
...@@ -11,7 +11,7 @@ The basic dependency packages include: ...@@ -11,7 +11,7 @@ The basic dependency packages include:
- @ohos.data.dataAbility - @ohos.data.dataAbility
- @ohos.data.rdb - @ohos.data.relationalStore
The sample code for accessing a DataAbility is as follows: The sample code for accessing a DataAbility is as follows:
...@@ -23,7 +23,7 @@ The sample code for accessing a DataAbility is as follows: ...@@ -23,7 +23,7 @@ The sample code for accessing a DataAbility is as follows:
// Different from the URI defined in the config.json file, the URI passed in the parameter has an extra slash (/), three slashes in total. // Different from the URI defined in the config.json file, the URI passed in the parameter has an extra slash (/), three slashes in total.
import featureAbility from '@ohos.ability.featureAbility' import featureAbility from '@ohos.ability.featureAbility'
import ohos_data_ability from '@ohos.data.dataAbility' import ohos_data_ability from '@ohos.data.dataAbility'
import ohos_data_rdb from '@ohos.data.rdb' import relationalStore from '@ohos.data.relationalStore'
let urivar = "dataability:///com.ix.DataAbility" let urivar = "dataability:///com.ix.DataAbility"
let DAHelper = featureAbility.acquireDataAbilityHelper(urivar); let DAHelper = featureAbility.acquireDataAbilityHelper(urivar);
......
...@@ -27,12 +27,14 @@ Instead of manual modification, OpenHarmony adopts the following processing: ...@@ -27,12 +27,14 @@ Instead of manual modification, OpenHarmony adopts the following processing:
## Constraints ## Constraints
1. When you switch a DataAbility to a DataShareExtensionAbility, only the URI prefix can be modified.![FAvsStage-uri](figures/FAvsStage-uri.png) 1. When you switch a DataAbility to a DataShareExtensionAbility, only the URI prefix can be modified.
2. The **DataShareHelper** class implements only certain APIs of **DataAbilityHelper**. For details about the APIs, see the table below. ![FAvsStage-uri](figures/FAvsStage-uri.png)
3. The **DataShareHelper** class implements only certain APIs of **DataAbilityHelper**. For details about the APIs, see the table below.
**Table 1** API compatibility when the FA model accesses a DataShareExtensionAbility of the stage model
**Table 1** APIs invoked when the FA model accesses a DataShareExtensionAbility of the stage model
| API| Provided by DataAbilityHelper| Provided by DataShareHelper| Compatible| | API| Provided by DataAbilityHelper| Provided by DataShareHelper| Compatible|
| -------- | -------- | -------- | -------- | | -------- | -------- | -------- | -------- |
| on | Yes| Yes| Yes| | on | Yes| Yes| Yes|
......
# AccessibilityExtensionAbility Development # AccessibilityExtensionAbility
The **AccessibilityExtensionAbility** module provides accessibility extension capabilities based on the **ExtensionAbility** framework. You can develop your accessibility applications by applying the **AccessibilityExtensionAbility** template to enhance usability. The **AccessibilityExtensionAbility** module provides accessibility extension capabilities based on the **ExtensionAbility** framework. You can develop your accessibility applications by applying the **AccessibilityExtensionAbility** template to enhance usability.
...@@ -10,14 +10,6 @@ The **AccessibilityExtensionAbility** module provides accessibility extension ca ...@@ -10,14 +10,6 @@ The **AccessibilityExtensionAbility** module provides accessibility extension ca
> >
> Model: stage > Model: stage
This document is organized as follows:
- [AccessibilityExtensionAbility Overview](#accessibilityextensionability-overview)
- [Creating an Accessibility Extension Service](#creating-an-accessibility-extension-service)
- [Processing an Accessibility Event](#processing-an-accessibility-event)
- [Declaring Capabilities of Accessibility Extension Services](#declaring-capabilities-of-accessibility-extension-services)
- [Enabling a Custom Accessibility Extension Service](#enabling-a-custom-accessibility-extension-service)
## AccessibilityExtensionAbility Overview ## AccessibilityExtensionAbility Overview
Accessibility is about giving equal access to everyone so that they can access and use information equally and conveniently under any circumstances. It helps narrow the digital divide between people of different classes, regions, ages, and health status in terms of information understanding, information exchange, and information utilization, so that they can participate in social life more conveniently and enjoy the benefits of technological advances. Accessibility is about giving equal access to everyone so that they can access and use information equally and conveniently under any circumstances. It helps narrow the digital divide between people of different classes, regions, ages, and health status in terms of information understanding, information exchange, and information utilization, so that they can participate in social life more conveniently and enjoy the benefits of technological advances.
......
# API Switching Overview # API Switching Overview
Due to the differences in the thread model and process model, certain APIs (marked with **FAModelOnly** in the SDK) can be used only in the FA model. When switching an application from the FA model to the stage model, replace the APIs marked with **FAModelOnly** in the application with the APIs supported in the stage model. This topic uses the switching of **startAbility()** as an example. Due to the differences in the thread model and process model, certain APIs can be used only in the FA model. They are marked with **FAModelOnly** in the SDK. When switching an application from the FA model to the stage model, replace the APIs marked with **FAModelOnly** in the application with the APIs supported in the stage model. This topic uses the switching of **startAbility()** as an example.
![api-switch-overview](figures/api-switch-overview.png) ![api-switch-overview](figures/api-switch-overview.png)
...@@ -27,7 +27,7 @@ Due to the differences in the thread model and process model, certain APIs (mark ...@@ -27,7 +27,7 @@ Due to the differences in the thread model and process model, certain APIs (mark
- Sample code of **startAbility()** in the stage model: - Sample code of **startAbility()** in the stage model:
```ts ```ts
// context is a member of the ability object and is required for invoking inside a non-ability object. // Context is a member of the ability object and is required for invoking inside a non-ability object.
// Pass in the Context object. // Pass in the Context object.
let wantInfo = { let wantInfo = {
bundleName: "com.example.myapplication", bundleName: "com.example.myapplication",
......
...@@ -6,14 +6,14 @@ Icons and labels are usually configured together. There is the application icon, ...@@ -6,14 +6,14 @@ Icons and labels are usually configured together. There is the application icon,
The application icon and label are used in **Settings**. For example, they are displayed in the application list in **Settings**. The entry icon is displayed on the device's home screen after the application is installed. The entry icon maps to a [UIAbility](uiability-overview.md) component. Therefore, an application can have multiple entry icons and entry labels. When you touch one of them, the corresponding UIAbility page is displayed. The application icon and label are used in **Settings**. For example, they are displayed in the application list in **Settings**. The entry icon is displayed on the device's home screen after the application is installed. The entry icon maps to a [UIAbility](uiability-overview.md) component. Therefore, an application can have multiple entry icons and entry labels. When you touch one of them, the corresponding UIAbility page is displayed.
**Figure 1** Icons and labels **Figure 1** Icons and labels
![application-component-configuration-stage](figures/application-component-configuration-stage.png) ![application-component-configuration-stage](figures/application-component-configuration-stage.png)
- **Configuring the bundle name** - **Configuring the bundle name**
The bundle name is specified by the **bundleName** field in the [app.json5 file](../quick-start/app-configuration-file.md) in the **AppScope** directory of the project. This field uniquely identifies an application. You are advised to use the reverse domain name notion, 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. The bundle name is specified by the **bundleName** field in the [app.json5 file](../quick-start/app-configuration-file.md) in the **AppScope** directory of the project. This field uniquely identifies an application. 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.
- **Configuring the application icon and label** - **Configuring the application icon and label**
...@@ -21,7 +21,7 @@ The application icon and label are used in **Settings**. For example, they are d ...@@ -21,7 +21,7 @@ The application icon and label are used in **Settings**. For example, they are d
The application icon is specified by the **icon** field in the [app.json5 file](../quick-start/app-configuration-file.md) in the **AppScope** directory of the project. The **icon** field must be set to the index of an image so that the image is displayed as the application icon. The application icon is specified by the **icon** field in the [app.json5 file](../quick-start/app-configuration-file.md) in the **AppScope** directory of the project. The **icon** field must be set to the index of an image so that the image is displayed as the application icon.
The application label is specified by the **label** field in the [app.json5 file](../quick-start/app-configuration-file.md) in the **AppScope** module of the project. The **label** field specifies the application name displayed to users. It must be set to the index of a string resource. The application label is specified by the **label** field in the [app.json5 file](../quick-start/app-configuration-file.md) in the **AppScope** directory of the project. The **label** field specifies the application name displayed to users. It must be set to the index of a string resource.
```json ```json
{ {
...@@ -37,7 +37,7 @@ The application icon and label are used in **Settings**. For example, they are d ...@@ -37,7 +37,7 @@ The application icon and label are used in **Settings**. For example, they are d
On the stage model, you can configure an entry icon and label for each application component. The entry icon and label are displayed on the home screen. On the stage model, you can configure an entry icon and label for each application component. The entry icon and label are displayed on the home screen.
The entry icon is configured by specifying **icon** under **abilities** in the [module.json5 file](../quick-start/module-configuration-file.md). For example, if you want to display the icon of the UIAbility component on the home screen, add **entity.system.home** to **entities** and **ohos.want.action.home** to **actions** under **skills**. If this field is configured for multiple UIAbility components of an application, multiple icons are displayed on the home screen, corresponding to their respective UIAbility component. The entry icon is configured by specifying **icon** under **abilities** in the [module.json5 file](../quick-start/module-configuration-file.md). For example, if you want to display the icon of the UIAbility component on the home screen, add **entity.system.home** to **entities** and **ohos.want.action.home** to **actions** under **skills**. If this field is configured for multiple UIAbility components of an application, multiple icons are displayed on the home screen, corresponding to their respective UIAbility components.
```json ```json
{ {
...@@ -65,33 +65,33 @@ The application icon and label are used in **Settings**. For example, they are d ...@@ -65,33 +65,33 @@ The application icon and label are used in **Settings**. For example, they are d
``` ```
OpenHarmony strictly controls applications without icons to prevent malicious applications from deliberately configuring no icon to block uninstall attempts. OpenHarmony strictly controls applications without icons to prevent malicious applications from deliberately configuring no icon to block uninstall attempts.
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). The rules for displaying the entry icon and entry label are as follows: To hide an application icon on 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). The rules for displaying the entry icon and entry label are as follows:
1. The HAP file contains UIAbility configuration. 1. The HAP file contains UIAbility configuration.
* An entry icon is set in the **abilities** field of the **module.json5** file. * An entry icon is set in the **abilities** field of the **module.json5** file.
* The application does not have the privilege to hide its icon from the home screen. * The application does not have the privilege to hide its icon on the home screen.
* The system uses the icon configured for the UIAbility as the entry icon and displays it on the home screen. Touching this icon will direct the user to the home page of the UIAbility. * The system uses the icon configured for the UIAbility as the entry icon and displays it on the home screen. Touching this icon will direct the user to the home page of the UIAbility.
* The system uses the label configured for the UIAbility as the entry label and displays it on the home screen. If no label is configured, the system uses the label specified in the **app.json5** file as the entry label and displays it on the home screen. * The system uses the label configured for the UIAbility as the entry label and displays it on the home screen. If no label is configured, the system uses the label specified in the **app.json5** file as the entry label and displays it on the home screen.
* The application has the privilege to hide its icon from the home screen. * The application has the privilege to hide its icon on the home screen.
* The application information is not returned when the home screen queries the information, and the entry icon and label of the application are not displayed on the home screen. * The application information is not returned when the home screen queries the information, and the entry icon and label of the application are not displayed on the home screen.
* No entry icon is set in the **abilities** field of the **module.json5** file. * No entry icon is set in the **abilities** field of the **module.json5** file.
* The application does not have the privilege to hide its icon from the home screen. * The application does not have the privilege to hide its icon on the home screen.
* The system uses the icon specified in the **app.json5** file as the entry icon and displays it on the home screen. Touching this icon will direct the user to the application details page, as shown below. * The system uses the icon specified in the **app.json5** file as the entry icon and displays it on the home screen. Touching this icon will direct the user to the application details page, as shown below.
* The system uses the label specified in the **app.json5** file as the entry label and displays it on the home screen. * The system uses the label specified in the **app.json5** file as the entry label and displays it on the home screen.
* The application has the privilege to hide its icon from the home screen. * The application has the privilege to hide its icon on the home screen.
* The application information is not returned when the home screen queries the information, and the entry icon and label of the application are not displayed on the home screen. * The application information is not returned when the home screen queries the information, and the entry icon and label of the application are not displayed on the home screen.
2. The HAP file does not contain UIAbility configuration. 2. The HAP file does not contain UIAbility configuration.
* The application does not have the privilege to hide its icon from the home screen. * The application does not have the privilege to hide its icon on the home screen.
* The system uses the icon specified in the **app.json5** file as the entry icon and displays it on the home screen. Touching this icon will direct the user to the application details page, as shown below. * The system uses the icon specified in the **app.json5** file as the entry icon and displays it on the home screen. Touching this icon will direct the user to the application details page, as shown below.
* The system uses the label specified in the **app.json5** file as the entry label and displays it on the home screen. * The system uses the label specified in the **app.json5** file as the entry label and displays it on the home screen.
* The application has the privilege to hide its icon from the home screen. * The application has the privilege to hide its icon on the home screen.
* The application information is not returned when the home screen queries the information, and the entry icon and label of the application are not displayed on the home screen. * The application information is not returned when the home screen queries the information, and the entry icon and label of the application are not displayed on the home screen.
**Figure 2** Application details page **Figure 2** Application details page
![Application details page](figures/application_details.jpg) ![Application details page](figures/application_details.jpg)
- **Configuring application version declaration** - **Configuring application version declaration**
To declare the application version, configure the **versionCode** and **versionName** fields in the [app.json5 file](../quick-start/app-configuration-file.md) in the **AppScope** directory of the project. **versionCode** specifies the version number of the application. The value is a 32-bit non-negative integer. It is used only to determine whether a version is later than another version. A larger value indicates a later version. **versionName** provides the text description of the version number. To declare the application version, configure the **versionCode** and **versionName** fields in the [app.json5 file](../quick-start/app-configuration-file.md) in the **AppScope** directory of the project. **versionCode** specifies the version number of the application. The value is a 32-bit non-negative integer. It is used only to determine whether a version is later than another version. A larger value indicates a later version. **versionName** provides the text description of the version number.
......
...@@ -44,17 +44,17 @@ For details about the APIs, see [API Reference](../reference/apis/js-apis-inner- ...@@ -44,17 +44,17 @@ For details about the APIs, see [API Reference](../reference/apis/js-apis-inner-
} }
``` ```
2. Set the display orientation of the host featureAbility. 2. Set the display orientation of the **featureAbility**.
```ts ```ts
import featureAbility from '@ohos.ability.featureAbility' import featureAbility from '@ohos.ability.featureAbility'
import bundle from '@ohos.bundle'; import bundleManager from '@ohos.bundle.bundleManager';
export default { export default {
onCreate() { onCreate() {
// Obtain the context and call related APIs. // Obtain the context and call related APIs.
let context = featureAbility.getContext(); let context = featureAbility.getContext();
context.setDisplayOrientation(bundle.DisplayOrientation.LANDSCAPE).then(() => { context.setDisplayOrientation(bundleManager.DisplayOrientation.LANDSCAPE).then(() => {
console.info("Set display orientation.") console.info("Set display orientation.")
}) })
console.info('Application onCreate') console.info('Application onCreate')
......
# Context (Stage Model) # Context (Stage Model)
## Overview ## Overview
[Context](../reference/apis/js-apis-inner-application-context.md) is the context of an object in an application. It provides basic information about the application, for example, **resourceManager**, **applicationInfo**, **dir** (application development path), and **area** (encrypted level). It also provides basic methods such as **createBundleContext()** and **getApplicationContext()**. The UIAbility component and ExtensionAbility derived class components have their own **Context** classes, for example, the base class **Context**, **ApplicationContext**, **AbilityStageContext**, **UIAbilityContext**, **ExtensionContext**, and **ServiceExtensionContext**. [Context](../reference/apis/js-apis-inner-application-context.md) is the context of an object in an application. It provides basic information about the application, for example, **resourceManager**, **applicationInfo**, **dir** (application file path), and **area** (encryption level). It also provides basic methods such as **createBundleContext()** and **getApplicationContext()**. The UIAbility component and ExtensionAbility derived class components have their own **Context** classes, for example, the base class **Context**, **ApplicationContext**, **AbilityStageContext**, **UIAbilityContext**, **ExtensionContext**, and **ServiceExtensionContext**.
- The figure below illustrates the inheritance relationship of contexts.
- The figure below illustrates the inheritance relationship of contexts.
![context-inheritance](figures/context-inheritance.png) ![context-inheritance](figures/context-inheritance.png)
- The figure below illustrates the holding relationship of contexts. - The figure below illustrates the holding relationship of contexts.
![context-holding](figures/context-holding.png)
The following describes the information provided by different contexts. ![context-holding](figures/context-holding.png)
- The following describes the information provided by different contexts.
- [UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md): Each UIAbility has the **Context** attribute, which provides APIs to operate an application component, obtain the application component configuration, and more. - [UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md): Each UIAbility has the **Context** attribute, which provides APIs to operate an application component, obtain the application component configuration, and more.
```ts ```ts
...@@ -67,79 +70,81 @@ The following describes the information provided by different contexts. ...@@ -67,79 +70,81 @@ The following describes the information provided by different contexts.
This topic describes how to use the context in the following scenarios: This topic describes how to use the context in the following scenarios:
- [Obtaining the Application Development Path](#obtaining-the-application-development-path) - [Obtaining Application File Paths](#obtaining-application-file-paths)
- [Obtaining and Modifying Encryption Levels](#obtaining-and-modifying-encryption-levels) - [Obtaining and Modifying Encryption Levels](#obtaining-and-modifying-encryption-levels)
- [Creating Context of Another Application or Module](#creating-context-of-another-application-or-module) - [Creating Context of Another Application or Module](#creating-context-of-another-application-or-module)
- [Subscribing to UIAbility Lifecycle Changes in a Process](#subscribing-to-uiability-lifecycle-changes-in-a-process) - [Subscribing to UIAbility Lifecycle Changes in a Process](#subscribing-to-uiability-lifecycle-changes-in-a-process)
### Obtaining the Application Development Path ### Obtaining Application File Paths
The following table describes the application development paths obtained from context. The base class [Context](../reference/apis/js-apis-inner-application-context.md) provides the capability of obtaining application file paths. **ApplicationContext**, **AbilityStageContext**, **UIAbilityContext**, and **ExtensionContext** inherit this capability. The application file paths are a type of application sandbox paths. For details, see [Application Sandbox Directory](../file-management/app-sandbox-directory.md).
**Table 1** Application development paths The application file paths obtained by the preceding contexts are different.
| Name| Type| Readable| Writable| Description| - The application file path obtained through **ApplicationContext** is at the application level. This path is recommended for storing global application information, and the files in the path will be deleted when the application is uninstalled.
| -------- | -------- | -------- | -------- | -------- |
| bundleCodeDir | string | Yes | No | Path for storing the application's installation package, that is, installation directory of the application on the internal storage. |
| cacheDir | string | Yes| No| Path for storing the cache files, that is, cache directory of the application on the internal storage.<br>It is the content of **Storage** of an application under **Settings > Apps & services > Apps**.|
| filesDir | string | Yes | No | Path for storing the common files, that is, file directory of the application on the internal storage.<br>Files in this directory may be synchronized to other directories during application migration or backup.|
| preferencesDir | string | Yes | Yes | Path for storing the preference files, that is, preferences directory of the application. |
| tempDir | string | Yes | No | Path for storing the temporary files.<br>Files in this directory are deleted after the application is uninstalled.|
| databaseDir | string | Yes | No | Path for storing the application's database, that is, storage directory of the local database. |
| distributedFilesDir | string | Yes| No| Path for storing the distributed files.|
The capability of obtaining the application development path is provided by the base class **Context**. This capability is also provided by **ApplicationContext**, **AbilityStageContext**, **UIAbilityContext**, and **ExtensionContext**. However, the paths obtained from different contexts may differ, as shown below. | Name| Path|
**Figure 1** Application development paths obtained from context
![context-dir](figures/context-dir.png)
- Obtain the application-level path through **ApplicationContext**. It is recommended that global application information be stored in this path. Files stored in this path will be deleted only when the application is uninstalled.
| Name| Path|
| -------- | -------- |
| bundleCodeDir | {Path prefix}/el1/bundle/|
| cacheDir | {Path prefix}/{Encryption level}/base/cache/|
| filesDir | {Path prefix}/{Encryption level}/base/files/|
| preferencesDir | {Path prefix}/{Encryption level}/base/preferences/|
| tempDir | {Path prefix}/{Encryption level}/base/temp/|
| databaseDir | {Path prefix}/{Encryption level}/database/|
| distributedFilesDir | {Path prefix}/el2/distributedFiles/|
- Obtain the HAP level path through **AbilityStageContext**, **UIAbilityContext**, and **ExtensionContext**. It is recommended that the HAP information be stored in this path. The file content stored in this path will be deleted when the HAP is uninstalled. The file content in the application-level path will be deleted only after all the HAPs of the application are uninstalled.
| Name| Path|
| -------- | -------- | | -------- | -------- |
| bundleCodeDir | {Path prefix}/el1/bundle/| | bundleCodeDir | <Path prefix>/el1/bundle/|
| cacheDir | {Path prefix}/{Encryption level}/base/**haps/{moduleName}**/cache/| | cacheDir | <Path prefix>/<Encryption level>/base/cache/|
| filesDir | {Path prefix}/{Encryption level}/base/**haps/{moduleName}**/files/| | filesDir | <Path prefix>/<Encryption level>/base/files/|
| preferencesDir | {Path prefix}/{Encryption level}/base/**haps/{moduleName}**/preferences/| | preferencesDir | <Path prefix>/<Encryption level>/base/preferences/|
| tempDir | {Path prefix}/{Encryption level}/base/**haps/{moduleName}**/temp/| | tempDir | <Path prefix>/<Encryption level>/base/temp/|
| databaseDir | {Path prefix}/{Encryption level}/database/**{moduleName}**/| | databaseDir | <Path prefix>/<Encryption level>/database/|
| distributedFilesDir | {Path prefix}/el2/distributedFiles/**{moduleName}**/| | distributedFilesDir | <Path prefix>/el2/distributedFiles/|
The sample code is as follows:
```ts
import UIAbility from '@ohos.app.ability.UIAbility';
export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) {
let applicationContext = this.context.getApplicationContext();
let cacheDir = applicationContext.cacheDir;
let tempDir = applicationContext.tempDir;
let filesDir = applicationContext.filesDir;
let databaseDir = applicationContext.databaseDir;
let bundleCodeDir = applicationContext.bundleCodeDir;
let distributedFilesDir = applicationContext.distributedFilesDir;
let preferencesDir = applicationContext.preferencesDir;
...
}
}
```
The sample code for obtaining the application development paths is as follows: - The application file path obtained through **AbilityStageContext**, **UIAbilityContext**, or **ExtensionContext** is at the HAP level. This path is recommended for storing HAP-related information, and the files in this path are deleted when the HAP is uninstalled. However, the deletion does not affect the files in the application-level path unless all HAPs of the application are uninstalled.
| Name| Path|
| -------- | -------- |
| bundleCodeDir | <Path prefix>/el1/bundle/|
| cacheDir | <Path prefix>/<Encryption level>/base/**haps/\<module-name>**/cache/|
| filesDir | <Path prefix>/<Encryption level>/base/**haps/\<module-name>**/files/|
| preferencesDir | <Path prefix>/<Encryption level>/base/**haps/\<module-name>**/preferences/|
| tempDir | <Path prefix>/<Encryption level>/base/**haps/\<module-name>**/temp/|
| databaseDir | <Path prefix>/<Encryption level>/database/**\<module-name>**/|
| distributedFilesDir | <Path prefix>/el2/distributedFiles/**\<module-name>**/|
```ts The sample code is as follows:
import UIAbility from '@ohos.app.ability.UIAbility';
export default class EntryAbility extends UIAbility { ```ts
onCreate(want, launchParam) { import UIAbility from '@ohos.app.ability.UIAbility';
let cacheDir = this.context.cacheDir;
let tempDir = this.context.tempDir; export default class EntryAbility extends UIAbility {
let filesDir = this.context.filesDir; onCreate(want, launchParam) {
let databaseDir = this.context.databaseDir; let cacheDir = this.context.cacheDir;
let bundleCodeDir = this.context.bundleCodeDir; let tempDir = this.context.tempDir;
let distributedFilesDir = this.context.distributedFilesDir; let filesDir = this.context.filesDir;
let preferencesDir = this.context.preferencesDir; let databaseDir = this.context.databaseDir;
... let bundleCodeDir = this.context.bundleCodeDir;
let distributedFilesDir = this.context.distributedFilesDir;
let preferencesDir = this.context.preferencesDir;
...
}
} }
} ```
```
> **NOTE**
>
> The sample code obtains the sandbox path of the application development path. The absolute path can be obtained by running the **find / -name <fileName>** command in the hdc shell after file creation or modification.
### Obtaining and Modifying Encryption Levels ### Obtaining and Modifying Encryption Levels
...@@ -153,22 +158,23 @@ In practice, you need to select a proper encryption level based on scenario-spec ...@@ -153,22 +158,23 @@ In practice, you need to select a proper encryption level based on scenario-spec
> >
> - AreaMode.EL2: user-level encryption. Directories with this encryption level are accessible only after the device is powered on and the password is entered (for the first time). > - AreaMode.EL2: user-level encryption. Directories with this encryption level are accessible only after the device is powered on and the password is entered (for the first time).
You can obtain and set the encryption level by reading and writing the [area attribute in Context](../reference/apis/js-apis-inner-application-context.md). You can obtain and set the encryption level by reading and writing the **area** attribute in [Context](../reference/apis/js-apis-inner-application-context.md).
```ts ```ts
import UIAbility from '@ohos.app.ability.UIAbility'; import UIAbility from '@ohos.app.ability.UIAbility';
import contextConstant from '@ohos.app.ability.contextConstant';
export default class EntryAbility extends UIAbility { export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) { onCreate(want, launchParam) {
// Before storing common information, switch the encryption level to EL1. // Before storing common information, switch the encryption level to EL1.
if (this.context.area === 1) {// Obtain the area. if (this.context.area === contextConstant.AreaMode.EL2) { // Obtain the area.
this.context.area = 0; // Modify the area. this.context.area = contextConstant.AreaMode.EL1; // Modify the area.
} }
// Store common information. // Store common information.
// Before storing sensitive information, switch the encryption level to EL2. // Before storing sensitive information, switch the encryption level to EL2.
if (this.context.area === 0) { // Obtain the area. if (this.context.area === contextConstant.AreaMode.EL1) { // Obtain the area.
this.context.area = 1; // Modify the area. this.context.area = contextConstant.AreaMode.EL2; // Modify the area.
} }
// Store sensitive information. // Store sensitive information.
} }
...@@ -178,7 +184,7 @@ export default class EntryAbility extends UIAbility { ...@@ -178,7 +184,7 @@ export default class EntryAbility extends UIAbility {
### Creating Context of Another Application or Module ### Creating Context of Another Application or Module
The base class **Context** provides [createBundleContext(bundleName:string)](../reference/apis/js-apis-inner-application-context.md#contextcreatebundlecontext), [createModuleContext(moduleName:string)](../reference/apis/js-apis-inner-application-context.md#contextcreatemodulecontext), and [createModuleContext(bundleName:string, moduleName:string)](../reference/apis/js-apis-inner-application-context.md#contextcreatemodulecontext-1) to create the context of other applications or modules, so as to obtain the resource information, for example, [obtaining the application development paths](#obtaining-the-application-development-path) of other modules. The base class **Context** provides [createBundleContext(bundleName:string)](../reference/apis/js-apis-inner-application-context.md#contextcreatebundlecontext), [createModuleContext(moduleName:string)](../reference/apis/js-apis-inner-application-context.md#contextcreatemodulecontext), and [createModuleContext(bundleName:string, moduleName:string)](../reference/apis/js-apis-inner-application-context.md#contextcreatemodulecontext-1) to create the context of other applications or modules, so as to obtain the resource information, for example, [obtaining application file paths](#obtaining-application-development-paths) of other modules.
- Call **createBundleContext(bundleName:string)** to create the context of another application. - Call **createBundleContext(bundleName:string)** to create the context of another application.
> **NOTE** > **NOTE**
...@@ -188,9 +194,9 @@ The base class **Context** provides [createBundleContext(bundleName:string)](../ ...@@ -188,9 +194,9 @@ The base class **Context** provides [createBundleContext(bundleName:string)](../
> - Request the **ohos.permission.GET_BUNDLE_INFO_PRIVILEGED** permission. For details, see [Declaring Permissions in the Configuration File](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file). > - Request the **ohos.permission.GET_BUNDLE_INFO_PRIVILEGED** permission. For details, see [Declaring Permissions in the Configuration File](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file).
> >
> - This is a system API and cannot be called by third-party applications. > - This is a system API and cannot be called by third-party applications.
For example, application information displayed on the home screen includes the application name and icon. The home screen application calls the foregoing method to obtain the context information, so as to obtain the resource information including the application name and icon. For example, application information displayed on the home screen includes the application name and icon. The home screen application calls the foregoing method to obtain the context information, so as to obtain the resource information including the application name and icon.
```ts ```ts
import UIAbility from '@ohos.app.ability.UIAbility'; import UIAbility from '@ohos.app.ability.UIAbility';
...@@ -203,7 +209,7 @@ The base class **Context** provides [createBundleContext(bundleName:string)](../ ...@@ -203,7 +209,7 @@ The base class **Context** provides [createBundleContext(bundleName:string)](../
} }
} }
``` ```
- Call **createModuleContext(bundleName:string, moduleName:string)** to obtain the context of a specified module of another application. After obtaining the context, you can obtain the resource information of that module. - Call **createModuleContext(bundleName:string, moduleName:string)** to obtain the context of a specified module of another application. After obtaining the context, you can obtain the resource information of that module.
> **NOTE** > **NOTE**
> >
......
...@@ -3,42 +3,45 @@ ...@@ -3,42 +3,45 @@
## Implementation Principles ## Implementation Principles
**Figure 1** ArkTS widget implementation principles **Figure 1** ArkTS widget implementation principles
![WidgetPrinciple](figures/WidgetPrinciple.png) ![WidgetPrinciple](figures/WidgetPrinciple.png)
- Widget host: an application that displays the widget content and controls the widget location. Only the system application can function as a widget host. - Widget host: an application that displays the widget content and controls the widget location. Only the system application can function as a widget host.
- Widget provider: an application that provides the widget content to display and controls how widget components are laid out and how they interact with users. - Widget provider: an application that provides the widget content to display and controls how widget components are laid out and how they interact with users.
- Widget Manager: a resident agent that manages widgets in the system. It provides the [formProvider](../reference/apis/js-apis-app-form-formProvider.md) and [formHost](../reference/apis/js-apis-app-form-formHost.md) APIs as well as widget management, usage, and periodic updates. - Widget Manager: a resident agent that manages widgets in the system. It provides the [formProvider](../reference/apis/js-apis-app-form-formProvider.md) and [formHost](../reference/apis/js-apis-app-form-formHost.md) APIs as well as the APIs for widget management, usage, and periodic updates.
- Widget rendering service: a service that manages widget rendering instances. Widget rendering instances are bound to the [widget components](../reference/arkui-ts/ts-basic-components-formcomponent.md) on the widget host on a one-to-one basis. The widget rendering service runs the widget page code **widgets.abc** for rendering, and sends the rendered data to the corresponding widget component on the widget host. - Widget rendering service: a service that manages widget rendering instances. Widget rendering instances are bound to the [widget components](../reference/arkui-ts/ts-basic-components-formcomponent.md) on the widget host on a one-to-one basis. The widget rendering service runs the widget page code **widgets.abc** for rendering, and sends the rendered data to the corresponding widget component on the widget host.
**Figure 2** Working principles of the ArkTS widget rendering service **Figure 2** Working principles of the ArkTS widget rendering service
![WidgetRender](figures/WidgetRender.png) ![WidgetRender](figures/WidgetRender.png)
Unlike JS widgets, ArkTS widgets support logic code running. To avoid potential ArkTS widget issues from affecting the use of applications, the widget page code **widgets.abc** is executed by the widget rendering service, which is managed by the Widget Manager. Each widget component of a widget host corresponds to a rendering instance in the widget rendering service. Rendering instances of an application provider run in the same virtual machine operating environment, and rendering instances of different application providers run in different virtual machine operating environments. In this way, the resources and state data are isolated between widgets of different application providers. During development, pay attention to the use of the [globalThis](uiability-data-sync-with-ui.md#using-globalthis-between-uiability-and-page) object. Use one **globalThis** object for widgets by the same application provider, and different **globalThis** objects for widgets by different application providers. Unlike JS widgets, ArkTS widgets support logic code running. The widget page code **widgets.abc** is executed by the widget rendering service, which is managed by the Widget Manager. Each widget component of a widget host corresponds to a rendering instance in the widget rendering service. Rendering instances of a widget provider run in the same virtual machine operating environment, and rendering instances of different widget providers run in different virtual machine operating environments. In this way, the resources and state data are isolated between widgets of different widget providers. During development, pay attention to the use of the [globalThis](uiability-data-sync-with-ui.md#using-globalthis-between-uiability-and-page) object. Use one **globalThis** object for widgets from the same widget provider, and different **globalThis** objects for widgets from different widget providers.
## Advantages of ArkTS Widgets ## Advantages of ArkTS Widgets
As a quick entry to applications, ArkTS widgets have the following advantages over JS widgets: As a quick entry to applications, ArkTS widgets outperform JS widgets in the following aspects:
- Improved development experience and efficiency, thanks to the unified development paradigm - Improved development experience and efficiency, thanks to the unified development paradigm
ArkTS widgets share the same declarative UI development framework as application pages. This means that the page layouts can be directly reused in widgets, improving development experience and efficiency. ArkTS widgets share the same declarative UI development framework as application pages. This means that the page layouts can be directly reused in widgets, improving development experience and efficiency.
**Figure 3** Comparison of widget project structures **Figure 3** Comparison of widget project structures
![WidgetProject](figures/WidgetProject.png) ![WidgetProject](figures/WidgetProject.png)
- More widget features - More widget features
- Animation: The ArkTS widget supports the [attribute animation](../reference/arkui-ts/ts-animatorproperty.md) and [explicit animation](../reference/arkui-ts/ts-explicit-animation.md) capabilities, which can be leveraged to deliver a more engaging experience. - Animation: ArkTS widgets support the [attribute animation](../reference/arkui-ts/ts-animatorproperty.md) and [explicit animation](../reference/arkui-ts/ts-explicit-animation.md) capabilities, which can be leveraged to deliver a more engaging experience.
- Custom drawing: The ArkTS widget allows you to draw graphics with the [Canvas](../reference/arkui-ts/ts-components-canvas-canvas.md) component to present information more vividly. - Custom drawing: ArkTS widgets allow you to draw graphics with the [\<Canvas>](../reference/arkui-ts/ts-components-canvas-canvas.md) component to present information more vividly.
- Logic code execution: The capability to run logic code in widgets means that service logic can be self-closed in widgets, expanding the service application scenarios of widgets. - Logic code execution: The capability to run logic code in widgets means that service logic can be self-closed in widgets, expanding the use cases of widgets.
## Constraints on ArkTS Widgets ## Constraints on ArkTS Widgets
Compared with JS widgets, ArkTS widgets provide more capabilities, but they are also more prone to malicious behavior. The ArkTS widget is displayed in the widget host, which is usually the home screen. To ensure user experience and power consumption, the ArkTS widget capability is restricted as follows: Compared with JS widgets, ArkTS widgets provide more capabilities, but they are also more prone to malicious behavior. To account for the impact on the widget host – typically the home screen, ArkTS widgets are subject to the following restrictions:
- The .so file cannot be loaded. - The .so file cannot be loaded.
...@@ -46,12 +49,14 @@ Compared with JS widgets, ArkTS widgets provide more capabilities, but they are ...@@ -46,12 +49,14 @@ Compared with JS widgets, ArkTS widgets provide more capabilities, but they are
- Only [partial](arkts-ui-widget-page-overview.md) components, events, animations, data management, state management, and API capabilities of the declarative paradigm are supported. - Only [partial](arkts-ui-widget-page-overview.md) components, events, animations, data management, state management, and API capabilities of the declarative paradigm are supported.
- The event processing of the widget is independent of that of the widget host. It is recommended that you do not use the left and right sliding components when the widget host supports left and right swipes to prevent gesture conflicts. - The event processing of the widget is independent of that of the widget host. To prevent gesture conflicts, avoid using swipers in the widget when the widget host supports left and right swipes.
The following features are coming to ArkTS widgets in later versions: In addition, ArkTS widgets do not support the following features:
- Breakpoint debugging - Importing modules
- import statements
- Instant preview - Instant preview
- Breakpoint debugging.
- Hot reload
...@@ -12,7 +12,7 @@ Component startup refers to the behavior of starting or connecting to an applica ...@@ -12,7 +12,7 @@ Component startup refers to the behavior of starting or connecting to an applica
To deliver a better user experience, OpenHarmony restricts the following behavior: To deliver a better user experience, OpenHarmony restricts the following behavior:
- A background application randomly displays a dialog box, such as an ads pop-up. - A background application randomly displays a dialog box, such as an ad pop-up.
- Background applications wake up each other. This type of behavior occupies system resources and increases power consumption, or even causes system frozen. - Background applications wake up each other. This type of behavior occupies system resources and increases power consumption, or even causes system frozen.
...@@ -34,14 +34,14 @@ In view of this, OpenHarmony formulates a set of component startup rules, as fol ...@@ -34,14 +34,14 @@ In view of this, OpenHarmony formulates a set of component startup rules, as fol
- **Before starting the ServiceAbility or DataAbility component of an application, verify the AssociateWakeUp field of the target application.** - **Before starting the ServiceAbility or DataAbility component of an application, verify the AssociateWakeUp field of the target application.**
- This rule applies only to cross-application scenarios. - This rule applies only to cross-application scenarios.
- This rule is valid only when the target component is ServiceAbility or DataAbility. - This rule is valid only when the target component is ServiceAbility or DataAbility.
- The ServiceAbility and DataAbility of an application can be accessed by others only when **AssociateWakeUp** of the target application is set to **true**. - The ServiceAbility and DataAbility of an application can be accessed by other applications only when **AssociateWakeUp** of the target application is set to **true**.
- The **AssociateWakeUp** field can be configured only for preset applications. For other applications, this field is set to **false** by default. - The **AssociateWakeUp** field can be configured only for preset applications. For other applications, this field is set to **false** by default.
> **NOTE** > **NOTE**
> 1. Component startup control has been implemented since OpenHarmony v3.2 Release. > 1. Component startup control has been implemented since OpenHarmony v3.2 Release.
> >
> 2. The new component startup rules are more strict than the original ones. You must be familiar with the new startup rules to prevent service exceptions. > 2. The new component startup rules are more strict than the original ones. Get familiar with the new startup rules to prevent service exceptions.
......
...@@ -4,8 +4,8 @@ ...@@ -4,8 +4,8 @@
The FA model uses the [config.json file](../quick-start/application-configuration-file-overview-fa.md) to describe the basic information about an application. An application can have multiple modules, and each module has a **config.json** file. The **config.json** file consists of three parts: **app**, **deviceConfig**, and **module**. The **app** tag is used to configure application-level attributes. If an application has multiple modules, the **app** configuration in each **config.json** file must be consistent. The FA model uses the [config.json file](../quick-start/application-configuration-file-overview-fa.md) to describe the basic information about an application. An application can have multiple modules, and each module has a **config.json** file. The **config.json** file consists of three parts: **app**, **deviceConfig**, and **module**. The **app** tag is used to configure application-level attributes. If an application has multiple modules, the **app** configuration in each **config.json** file must be consistent.
The stage model uses the [app.json5](../quick-start/app-configuration-file.md) and [module.json](../quick-start/module-configuration-file.md) files to describe the basic information about an application. An application can have multiple modules but only one **app.json5** file. This file is used to configure application-level attributes and takes effect for all the modules. Each module has a **module.json5** file, which is used to configure module-level attributes and takes effect only for the current module. The stage model uses the [app.json5](../quick-start/app-configuration-file.md) and [module.json](../quick-start/module-configuration-file.md) files to describe the basic information about an application. An application can have multiple modules but only one **app.json5** file. This file is used to configure application-level attributes and the configuration applies to all the modules. Each module has a **module.json5** file, which is used to configure module-level attributes and the configuration applies only for the current module.
**Figure 1** Configuration file differences **Figure 1** Configuration file differences
![comparison-of-configuration-file](figures/comparison-of-configuration-file.png)
![comparison-of-configuration-file](figures/comparison-of-configuration-file.png)
\ No newline at end of file
...@@ -16,14 +16,14 @@ The following sample code enables the PageAbility to create connection callback ...@@ -16,14 +16,14 @@ The following sample code enables the PageAbility to create connection callback
```ts ```ts
import rpc from "@ohos.rpc" import rpc from "@ohos.rpc"
import prompt from '@system.prompt' import promptAction from '@ohos.promptAction'
import featureAbility from '@ohos.ability.featureAbility' import featureAbility from '@ohos.ability.featureAbility'
let option = { let option = {
onConnect: function onConnectCallback(element, proxy) { onConnect: function onConnectCallback(element, proxy) {
console.info(`onConnectLocalService onConnectDone`) console.info(`onConnectLocalService onConnectDone`)
if (proxy === null) { if (proxy === null) {
prompt.showToast({ promptAction.showToast({
message: "Connect service failed" message: "Connect service failed"
}) })
return return
...@@ -33,19 +33,19 @@ let option = { ...@@ -33,19 +33,19 @@ let option = {
let option = new rpc.MessageOption() let option = new rpc.MessageOption()
data.writeInterfaceToken("connect.test.token") data.writeInterfaceToken("connect.test.token")
proxy.sendRequest(0, data, reply, option) proxy.sendRequest(0, data, reply, option)
prompt.showToast({ promptAction.showToast({
message: "Connect service success" message: "Connect service success"
}) })
}, },
onDisconnect: function onDisconnectCallback(element) { onDisconnect: function onDisconnectCallback(element) {
console.info(`onConnectLocalService onDisconnectDone element:${element}`) console.info(`onConnectLocalService onDisconnectDone element:${element}`)
prompt.showToast({ promptAction.showToast({
message: "Disconnect service success" message: "Disconnect service success"
}) })
}, },
onFailed: function onFailedCallback(code) { onFailed: function onFailedCallback(code) {
console.info(`onConnectLocalService onFailed errCode:${code}`) console.info(`onConnectLocalService onFailed errCode:${code}`)
prompt.showToast({ promptAction.showToast({
message: "Connect local service onFailed" message: "Connect local service onFailed"
}) })
} }
......
# Context Switching # Context Switching
| API in the FA Model| Corresponding d.ts File in the Stage Model| Corresponding API or Field in the Stage Model| | API in the FA Model| Corresponding .d.ts File in the Stage Model| Corresponding API or Field in the Stage Model|
| -------- | -------- | -------- | | -------- | -------- | -------- |
| [getOrCreateLocalDir(callback:AsyncCallback&lt;string&gt;):void;](../reference/apis/js-apis-inner-app-context.md#contextgetorcreatelocaldir7)<br>[getOrCreateLocalDir():Promise&lt;string&gt;;](../reference/apis/js-apis-inner-app-context.md#contextgetorcreatelocaldir7-1) | There is no corresponding API in the stage model.| Applications developed on the stage model do not have the operation permission in the application root directory. Therefore, no corresponding API is provided.| | [getOrCreateLocalDir(callback:AsyncCallback&lt;string&gt;):void;](../reference/apis/js-apis-inner-app-context.md#contextgetorcreatelocaldir7)<br>[getOrCreateLocalDir():Promise&lt;string&gt;;](../reference/apis/js-apis-inner-app-context.md#contextgetorcreatelocaldir7-1) | There is no corresponding API in the stage model.| Applications developed on the stage model do not have the operation permission in the application root directory. Therefore, no corresponding API is provided.|
| [verifyPermission(permission:string,options:PermissionOptions,callback:AsyncCallback&lt;number&gt;):void;](../reference/apis/js-apis-inner-app-context.md#contextverifypermission7)<br>[verifyPermission(permission:string,callback:AsyncCallback&lt;number&gt;):void;](../reference/apis/js-apis-inner-app-context.md#contextverifypermission7-1)<br>[verifyPermission(permission:string,options?:PermissionOptions):Promise&lt;number&gt;;](../reference/apis/js-apis-inner-app-context.md#contextverifypermission7-2) | \@ohos.abilityAccessCtrl.d.ts | [verifyAccessTokenSync(tokenID: number, permissionName: Permissions): GrantStatus;](../reference/apis/js-apis-abilityAccessCtrl.md#verifyaccesstokensync9)<br>[verifyAccessToken(tokenID: number, permissionName: Permissions): Promise&lt;GrantStatus&gt;;](../reference/apis/js-apis-abilityAccessCtrl.md#verifyaccesstoken9) | | [verifyPermission(permission:string,options:PermissionOptions,callback:AsyncCallback&lt;number&gt;):void;](../reference/apis/js-apis-inner-app-context.md#contextverifypermission7)<br>[verifyPermission(permission:string,callback:AsyncCallback&lt;number&gt;):void;](../reference/apis/js-apis-inner-app-context.md#contextverifypermission7-1)<br>[verifyPermission(permission:string,options?:PermissionOptions):Promise&lt;number&gt;;](../reference/apis/js-apis-inner-app-context.md#contextverifypermission7-2) | \@ohos.abilityAccessCtrl.d.ts | [verifyAccessTokenSync(tokenID: number, permissionName: Permissions): GrantStatus;](../reference/apis/js-apis-abilityAccessCtrl.md#verifyaccesstokensync9)<br>[verifyAccessToken(tokenID: number, permissionName: Permissions): Promise&lt;GrantStatus&gt;;](../reference/apis/js-apis-abilityAccessCtrl.md#verifyaccesstoken9) |
| [requestPermissionsFromUser(permissions:Array&lt;string&gt;,requestCode:number,resultCallback:AsyncCallback&lt;PermissionRequestResult&gt;):void;](../reference/apis/js-apis-inner-app-context.md#contextrequestpermissionsfromuser7)<br/>[requestPermissionsFromUser(permissions:Array&lt;string&gt;,requestCode:number):Promise&lt;PermissionRequestResult&gt;;](../reference/apis/js-apis-inner-app-context.md#contextrequestpermissionsfromuser7-1) | \@ohos.abilityAccessCtrl.d.ts | [requestPermissionsFromUser(context: Context, permissionList: Array&lt;Permissions&gt;, requestCallback: AsyncCallback&lt;PermissionRequestResult&gt;) : void;](../reference/apis/js-apis-abilityAccessCtrl.md#requestpermissionsfromuser9)<br/>[requestPermissionsFromUser(context: Context, permissionList: Array&lt;Permissions&gt;) : Promise&lt;PermissionRequestResult&gt;;](../reference/apis/js-apis-abilityAccessCtrl.md#requestpermissionsfromuser9-1) | | [requestPermissionsFromUser(permissions:Array&lt;string&gt;,requestCode:number,resultCallback:AsyncCallback&lt;PermissionRequestResult&gt;):void;](../reference/apis/js-apis-inner-app-context.md#contextrequestpermissionsfromuser7)<br>[requestPermissionsFromUser(permissions:Array&lt;string&gt;,requestCode:number):Promise&lt;PermissionRequestResult&gt;;](../reference/apis/js-apis-inner-app-context.md#contextrequestpermissionsfromuser7-1) | \@ohos.abilityAccessCtrl.d.ts | [requestPermissionsFromUser(context: Context, permissionList: Array&lt;Permissions&gt;, requestCallback: AsyncCallback&lt;PermissionRequestResult&gt;) : void;](../reference/apis/js-apis-abilityAccessCtrl.md#requestpermissionsfromuser9)<br>[requestPermissionsFromUser(context: Context, permissionList: Array&lt;Permissions&gt;) : Promise&lt;PermissionRequestResult&gt;;](../reference/apis/js-apis-abilityAccessCtrl.md#requestpermissionsfromuser9-1) |
| [getApplicationInfo(callback:AsyncCallback&lt;ApplicationInfo&gt;):void;](../reference/apis/js-apis-inner-app-context.md#contextgetapplicationinfo7)<br>[getApplicationInfo():Promise&lt;ApplicationInfo&gt;;](../reference/apis/js-apis-inner-app-context.md#contextgetapplicationinfo7-1) | application\Context.d.ts | [applicationInfo: ApplicationInfo;](../reference/apis/js-apis-inner-application-context.md#attributes)| | [getApplicationInfo(callback:AsyncCallback&lt;ApplicationInfo&gt;):void;](../reference/apis/js-apis-inner-app-context.md#contextgetapplicationinfo7)<br>[getApplicationInfo():Promise&lt;ApplicationInfo&gt;;](../reference/apis/js-apis-inner-app-context.md#contextgetapplicationinfo7-1) | application\Context.d.ts | [applicationInfo: ApplicationInfo;](../reference/apis/js-apis-inner-application-context.md#attributes)|
| [getBundleName(callback : AsyncCallback&lt;string&gt;): void;](../reference/apis/js-apis-inner-app-context.md#contextgetbundlename7)<br>[getBundleName(): Promise&lt;string&gt;;](../reference/apis/js-apis-inner-app-context.md#contextgetbundlename7-1) | application\UIAbilityContext.d.ts | [abilityInfo.bundleName: string;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#attributes)| | [getBundleName(callback : AsyncCallback&lt;string&gt;): void;](../reference/apis/js-apis-inner-app-context.md#contextgetbundlename7)<br>[getBundleName(): Promise&lt;string&gt;;](../reference/apis/js-apis-inner-app-context.md#contextgetbundlename7-1) | application\UIAbilityContext.d.ts | [abilityInfo.bundleName: string;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#attributes)|
| [getDisplayOrientation(callback : AsyncCallback&lt;bundle.DisplayOrientation&gt;): void;](../reference/apis/js-apis-inner-app-context.md#contextgetdisplayorientation7)<br>[getDisplayOrientation(): Promise&lt;bundle.DisplayOrientation&gt;;](../reference/apis/js-apis-inner-app-context.md#contextgetdisplayorientation7-1) | \@ohos.screen.d.ts | [readonly orientation: Orientation;](../reference/apis/js-apis-screen.md#orientation) | | [getDisplayOrientation(callback : AsyncCallback&lt;bundle.DisplayOrientation&gt;): void;](../reference/apis/js-apis-inner-app-context.md#contextgetdisplayorientation7)<br>[getDisplayOrientation(): Promise&lt;bundle.DisplayOrientation&gt;;](../reference/apis/js-apis-inner-app-context.md#contextgetdisplayorientation7-1) | \@ohos.screen.d.ts | [readonly orientation: Orientation;](../reference/apis/js-apis-screen.md#orientation) |
...@@ -26,3 +26,5 @@ ...@@ -26,3 +26,5 @@
| [getAbilityInfo(callback:AsyncCallback&lt;AbilityInfo&gt;):void;](../reference/apis/js-apis-inner-app-context.md#contextgetabilityinfo7)<br>[getAbilityInfo():Promise&lt;AbilityInfo&gt;;](../reference/apis/js-apis-inner-app-context.md#contextgetabilityinfo7-1) | application\UIAbilityContext.d.ts | [abilityInfo: AbilityInfo;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#attributes)| | [getAbilityInfo(callback:AsyncCallback&lt;AbilityInfo&gt;):void;](../reference/apis/js-apis-inner-app-context.md#contextgetabilityinfo7)<br>[getAbilityInfo():Promise&lt;AbilityInfo&gt;;](../reference/apis/js-apis-inner-app-context.md#contextgetabilityinfo7-1) | application\UIAbilityContext.d.ts | [abilityInfo: AbilityInfo;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#attributes)|
| [isUpdatingConfigurations(callback:AsyncCallback&lt;boolean&gt;):void;](../reference/apis/js-apis-inner-app-context.md#contextisupdatingconfigurations7)<br>[isUpdatingConfigurations():Promise&lt;boolean&gt;;](../reference/apis/js-apis-inner-app-context.md#contextisupdatingconfigurations7-1) | There is no corresponding API in the stage model.| OpenHarmony applications do not restart when the system environment changes. The **onConfigurationUpdated** callback is invoked to notify the applications of the changes. This API provides an empty implementation in the FA model, and the stage model does not provide a corresponding API.| | [isUpdatingConfigurations(callback:AsyncCallback&lt;boolean&gt;):void;](../reference/apis/js-apis-inner-app-context.md#contextisupdatingconfigurations7)<br>[isUpdatingConfigurations():Promise&lt;boolean&gt;;](../reference/apis/js-apis-inner-app-context.md#contextisupdatingconfigurations7-1) | There is no corresponding API in the stage model.| OpenHarmony applications do not restart when the system environment changes. The **onConfigurationUpdated** callback is invoked to notify the applications of the changes. This API provides an empty implementation in the FA model, and the stage model does not provide a corresponding API.|
| [printDrawnCompleted(callback:AsyncCallback&lt;void&gt;):void;](../reference/apis/js-apis-inner-app-context.md#contextprintdrawncompleted7)<br>[printDrawnCompleted():Promise&lt;void&gt;;](../reference/apis/js-apis-inner-app-context.md#contextprintdrawncompleted7-1) | There is no corresponding API in the stage model.| This API provides an empty implementation in the FA model. The stage model does not provide a corresponding API.| | [printDrawnCompleted(callback:AsyncCallback&lt;void&gt;):void;](../reference/apis/js-apis-inner-app-context.md#contextprintdrawncompleted7)<br>[printDrawnCompleted():Promise&lt;void&gt;;](../reference/apis/js-apis-inner-app-context.md#contextprintdrawncompleted7-1) | There is no corresponding API in the stage model.| This API provides an empty implementation in the FA model. The stage model does not provide a corresponding API.|
<!--no_check-->
\ No newline at end of file
...@@ -9,18 +9,18 @@ The following sample code shows how to create a DataAbility: ...@@ -9,18 +9,18 @@ The following sample code shows how to create a DataAbility:
```ts ```ts
import featureAbility from '@ohos.ability.featureAbility' import featureAbility from '@ohos.ability.featureAbility'
import dataAbility from '@ohos.data.dataAbility' import dataAbility from '@ohos.data.dataAbility'
import dataRdb from '@ohos.data.rdb' import relationalStore from '@ohos.data.relationalStore'
const TABLE_NAME = 'book' const TABLE_NAME = 'book'
const STORE_CONFIG = { name: 'book.db' } const STORE_CONFIG = { name: 'book.db' }
const SQL_CREATE_TABLE = 'CREATE TABLE IF NOT EXISTS book(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, introduction TEXT NOT NULL)' const SQL_CREATE_TABLE = 'CREATE TABLE IF NOT EXISTS book(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, introduction TEXT NOT NULL)'
let rdbStore: dataRdb.RdbStore = undefined let rdbStore: relationalStore.RdbStore = undefined
export default { export default {
onInitialized(abilityInfo) { onInitialized(abilityInfo) {
console.info('DataAbility onInitialized, abilityInfo:' + abilityInfo.bundleName) console.info('DataAbility onInitialized, abilityInfo:' + abilityInfo.bundleName)
let context = featureAbility.getContext() let context = featureAbility.getContext()
dataRdb.getRdbStore(context, STORE_CONFIG, 1, (err, store) => { relationalStore.getRdbStore(context, STORE_CONFIG, (err, store) => {
console.info('DataAbility getRdbStore callback') console.info('DataAbility getRdbStore callback')
store.executeSql(SQL_CREATE_TABLE, []) store.executeSql(SQL_CREATE_TABLE, [])
rdbStore = store rdbStore = store
......
...@@ -7,9 +7,9 @@ The DataAbility component in the FA model corresponds to the DataShareExtensionA ...@@ -7,9 +7,9 @@ The DataAbility component in the FA model corresponds to the DataShareExtensionA
The DataShareExtensionAbility class provides system APIs. Only system applications can create DataShareExtensionAbility instances. Therefore, DataAbility switching adopts different policies for system applications and third-party applications. The DataShareExtensionAbility class provides system APIs. Only system applications can create DataShareExtensionAbility instances. Therefore, DataAbility switching adopts different policies for system applications and third-party applications.
## Switching a DataAbility of a System Application ## Switching a DataAbility for a System Application
The procedure for switching a DataAbility of a system application is similar to the procedure of PageAbility switching. The procedure for switching a DataAbility for a system application is similar to the procedure of PageAbility switching.
1. Create a DataShareExtensionAbility in the stage model. 1. Create a DataShareExtensionAbility in the stage model.
...@@ -34,7 +34,7 @@ The procedure for switching a DataAbility of a system application is similar to ...@@ -34,7 +34,7 @@ The procedure for switching a DataAbility of a system application is similar to
| call?(method: string, arg: string, extras: PacMap, callback: AsyncCallback&lt;PacMap&gt;): void | NA | This method is not provided in the stage model. You need to implement the functionality based on service functions.| | call?(method: string, arg: string, extras: PacMap, callback: AsyncCallback&lt;PacMap&gt;): void | NA | This method is not provided in the stage model. You need to implement the functionality based on service functions.|
## Switching a DataAbility of a Third-Party Application ## Switching a DataAbility for a Third-Party Application
In the stage model, third-party applications cannot provide data services for other third-party applications. You can select a switching solution based on your service requirements. In the stage model, third-party applications cannot provide data services for other third-party applications. You can select a switching solution based on your service requirements.
......
# DataAbilityHelper Switching # DataAbilityHelper Switching
| API in the FA Model| Corresponding d.ts File in the Stage Model| Corresponding API in the Stage Model| | API in the FA Model| Corresponding .d.ts File in the Stage Model| Corresponding API in the Stage Model|
| -------- | -------- | -------- | | -------- | -------- | -------- |
| [openFile(uri: string, mode: string, callback: AsyncCallback&lt;number&gt;): void;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperopenfile)<br>[openFile(uri: string, mode: string): Promise&lt;number&gt;;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperopenfile-1) | \@ohos.data.fileAccess.d.ts | [openFile(uri: string, flags: OPENFLAGS) : Promise&lt;number&gt;;](../reference/apis/js-apis-fileAccess.md#fileaccesshelperopenfile)<br>[openFile(uri: string, flags: OPENFLAGS, callback: AsyncCallback&lt;number&gt;) : void;](../reference/apis/js-apis-fileAccess.md#fileaccesshelperopenfile) | | [openFile(uri: string, mode: string, callback: AsyncCallback&lt;number&gt;): void;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperopenfile)<br>[openFile(uri: string, mode: string): Promise&lt;number&gt;;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperopenfile-1) | \@ohos.data.fileAccess.d.ts | [openFile(uri: string, flags: OPENFLAGS) : Promise&lt;number&gt;;](../reference/apis/js-apis-fileAccess.md#fileaccesshelperopenfile)<br>[openFile(uri: string, flags: OPENFLAGS, callback: AsyncCallback&lt;number&gt;) : void;](../reference/apis/js-apis-fileAccess.md#fileaccesshelperopenfile) |
| [on(type: 'dataChange', uri: string, callback: AsyncCallback&lt;void&gt;): void;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperon) | \@ohos.data.dataShare.d.ts | [on(type: 'dataChange', uri: string, callback: AsyncCallback&lt;void&gt;): void;](../reference/apis/js-apis-data-dataShare.md#ondatachange) | | [on(type: 'dataChange', uri: string, callback: AsyncCallback&lt;void&gt;): void;](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md#dataabilityhelperon) | \@ohos.data.dataShare.d.ts | [on(type: 'dataChange', uri: string, callback: AsyncCallback&lt;void&gt;): void;](../reference/apis/js-apis-data-dataShare.md#ondatachange) |
......
# ExtensionAbility Component Overview # ExtensionAbility Overview
The ExtensionAbility component is used for specific scenarios such as widgets and input methods. The ExtensionAbility component is used for specific scenarios such as widget development and input method development.
An [ExtensionAbilityType](../reference/apis/js-apis-bundleManager.md#extensionabilitytype) is provided for every specific scenario. All types of ExtensionAbility components are managed by the corresponding system services in a unified manner. For example, the InputMethodExtensionAbility component is managed by the input method management service. The following ExtensionAbility types are supported: An [ExtensionAbility type](../reference/apis/js-apis-bundleManager.md#extensionabilitytype) is provided for every specific scenario. All types of ExtensionAbility components are managed by the corresponding system services in a unified manner. For example, the InputMethodExtensionAbility component is managed by the input method management service. The following ExtensionAbility types are supported:
- [FormExtensionAbility](../reference/apis/js-apis-app-form-formExtensionAbility.md): ExtensionAbility component of the form type, which provides APIs related to widgets. - [FormExtensionAbility](../reference/apis/js-apis-app-form-formExtensionAbility.md): ExtensionAbility component of the form type, which provides APIs related to widgets.
...@@ -13,7 +13,7 @@ An [ExtensionAbilityType](../reference/apis/js-apis-bundleManager.md#extensionab ...@@ -13,7 +13,7 @@ An [ExtensionAbilityType](../reference/apis/js-apis-bundleManager.md#extensionab
- [InputMethodExtensionAbility](../reference/apis/js-apis-inputmethod.md): ExtensionAbility component of the input_method type, which is used to develop input method applications. - [InputMethodExtensionAbility](../reference/apis/js-apis-inputmethod.md): ExtensionAbility component of the input_method type, which is used to develop input method applications.
- [ServiceExtensionAbility](../reference/apis/js-apis-app-ability-serviceExtensionAbility.md): ExtensionAbility component of the service type, which provides APIs related to background service scenarios. - [ServiceExtensionAbility](../reference/apis/js-apis-app-ability-serviceExtensionAbility.md): ExtensionAbility component of the service type, which provides APIs related to background services.
- [AccessibilityExtensionAbility](../reference/apis/js-apis-application-accessibilityExtensionAbility.md): ExtensionAbility component of the accessibility type, which provides APIs related to the accessibility feature. - [AccessibilityExtensionAbility](../reference/apis/js-apis-application-accessibilityExtensionAbility.md): ExtensionAbility component of the accessibility type, which provides APIs related to the accessibility feature.
...@@ -26,16 +26,15 @@ An [ExtensionAbilityType](../reference/apis/js-apis-bundleManager.md#extensionab ...@@ -26,16 +26,15 @@ An [ExtensionAbilityType](../reference/apis/js-apis-bundleManager.md#extensionab
- [EnterpriseAdminExtensionAbility](../reference/apis/js-apis-EnterpriseAdminExtensionAbility.md): ExtensionAbility component of the enterprise_admin type, which provides APIs for processing enterprise management events, such as application installation events on devices and events indicating too many incorrect screen-lock password attempts. - [EnterpriseAdminExtensionAbility](../reference/apis/js-apis-EnterpriseAdminExtensionAbility.md): ExtensionAbility component of the enterprise_admin type, which provides APIs for processing enterprise management events, such as application installation events on devices and events indicating too many incorrect screen-lock password attempts.
> **NOTE** > **NOTE**
> >
> 1. Third-party applications cannot implement ServiceExtensionAbility, DataShareExtensionAbility, StaticSubscriberExtensionAbility, or WindowExtensionAbility. >- Third-party applications cannot implement ServiceExtensionAbility, DataShareExtensionAbility, StaticSubscriberExtensionAbility, or WindowExtensionAbility. They can use other types of ExtensionAbility components that have been defined.
> >
> 2. To implement transaction processing in the background for a third-party application, use background tasks rather than ServiceExtensionAbility. For details, see [Background Task](../task-management/background-task-overview.md). >- To implement transaction processing in the background for a third-party application, use background tasks rather than ServiceExtensionAbility. For details, see [Background Task](../task-management/background-task-overview.md).
>
> 3. Third-party applications can use other types of ExtensionAbility components that have been defined.
## Using ExtensionAbility of the Specified Type ## Using ExtensionAbility of the Specified Type
All types of ExtensionAbility components are started by the corresponding system management service, rather than applications, so that their lifecycles are under control by the system. The caller of the ExtensionAbility component does not need to care about its lifecycle. Each type of ExtensionAbility component is started by the corresponding system management service, rather than applications, so that its lifecycle is under system control. The caller of the ExtensionAbility component does not need to care about its lifecycle.
The following uses [InputMethodExtensionAbility](../reference/apis/js-apis-inputmethod.md) as an example. As shown in the figure below, when an application calls the InputMethodExtensionAbility component, the input method management service is called first. The input method management service starts the InputMethodExtensionAbility component, returns the component to the application, and starts to manage its lifecycle. The following uses [InputMethodExtensionAbility](../reference/apis/js-apis-inputmethod.md) as an example. As shown in the figure below, when an application calls the InputMethodExtensionAbility component, the input method management service is called first. The input method management service starts the InputMethodExtensionAbility component, returns the component to the application, and starts to manage its lifecycle.
...@@ -46,18 +45,18 @@ The following uses [InputMethodExtensionAbility](../reference/apis/js-apis-input ...@@ -46,18 +45,18 @@ The following uses [InputMethodExtensionAbility](../reference/apis/js-apis-input
## Implementing ExtensionAbility of the Specified Type ## Implementing ExtensionAbility of the Specified Type
The following uses [FormExtensionAbility](../reference/apis/js-apis-app-form-formExtensionAbility.md) as an example. The widget framework provides the base class [FormExtensionAbility](../reference/apis/js-apis-app-form-formExtensionAbility.md). You derive this base class to create your own class (such as **MyFormExtensionAbility**), implement the callbacks, such as **onCreate()** and **onUpdateForm()**, to provide specific widget functionalities. For details, see [FormExtensionAbility](service-widget-overview.md). The following uses [FormExtensionAbility](../reference/apis/js-apis-app-form-formExtensionAbility.md) as an example. The widget framework provides the base class [FormExtensionAbility](../reference/apis/js-apis-app-form-formExtensionAbility.md). You can derive this base class to create your own class (for example, **MyFormExtensionAbility**) and implement the callbacks, such as **onCreate()** and **onUpdateForm()**, to provide specific widget features. For details, see [FormExtensionAbility](service-widget-overview.md).
You do not need to care when to add or delete a widget. The lifecycle of the FormExtensionAbility instance and the lifecycle of the ExtensionAbility process where the FormExtensionAbility instance is located are scheduled and managed by FormManagerService. You do not need to care when to add or delete a widget. The lifecycle of the FormExtensionAbility instance and the lifecycle of the ExtensionAbility process where the FormExtensionAbility instance is located are managed by FormManagerService.
![form_extension](figures/form_extension.png) ![form_extension](figures/form_extension.png)
> **NOTE** > **NOTE**
> >
> For an application, all ExtensionAbility components of the same type run in an independent process, whereas UIAbility, ServiceExtensionAbility, and DataShareExtensionAbility run in another independent process. For details, see [Process Model (Stage Model)](process-model-stage.md). > For an application, all ExtensionAbility components of the same type run in an independent process, whereas the UIAbility, ServiceExtensionAbility, and DataShareExtensionAbility components run in another independent process. For details, see [Process Model (Stage Model)](process-model-stage.md).
> >
> For example, an application has one UIAbility component, one ServiceExtensionAbility, one DataShareExtensionAbility, two FormExtensionAbility, and one ImeExtensionAbility. When the application is running, there are three processes: > For example, if an application has one UIAbility component, one ServiceExtensionAbility component, one DataShareExtensionAbility component, two FormExtensionAbility components, and one ImeExtensionAbility component, there will be three processes when the application is running.
> >
> - UIAbility, ServiceExtensionAbility, and DataShareExtensionAbility run in an independent process. > - UIAbility, ServiceExtensionAbility, and DataShareExtensionAbility run in an independent process.
> >
......
...@@ -4,22 +4,23 @@ ...@@ -4,22 +4,23 @@
The FA model is supported by API version 8 and earlier versions, and the stage model is recommended since API version 9. The FA model and stage model have their respective components. The FA model provides three types of application components: PageAbility, ServiceAbility, and DataAbility. The stage model provides two types of application components: UIAbility and ExtensionAbility. The FA model is supported by API version 8 and earlier versions, and the stage model is recommended since API version 9. The FA model and stage model have their respective components. The FA model provides three types of application components: PageAbility, ServiceAbility, and DataAbility. The stage model provides two types of application components: UIAbility and ExtensionAbility.
You cannot use both models for the development of an application (see the figure below). However, a device (system) can contain applications developed on both models (scenario 3 in the figure below). In this case, their components may interact with each other. You cannot use both models for the development of an application (see the figure below). However, a device (system) can contain applications developed on different models (scenario 3 in the figure below). In this case, their components may interact with each other.
**Figure 1** Coexistent application components of the FA model and stage model
Figure 1 Coexistent application components of the FA model and stage model
![coexistence-of-FAandStage](figures/coexistence-of-FAandStage.png) ![coexistence-of-FAandStage](figures/coexistence-of-FAandStage.png)
The following table lists the possible interaction scenarios. You must pay attention to the concerns listed below during your application development. The following table lists the possible interaction scenarios and the concerns of each scenario.
Table 1 Application component interaction scenarios **Table 1** Application component interaction scenarios
| Interaction Scenario| Concerns| | Interaction Scenario| Concerns|
| -------- | -------- | | -------- | -------- |
| [Starting a UIAbility from the FA Model](start-uiability-from-fa.md) | Set **bundleName** and **abilityName** in the **want** parameter to the bundle name and ability name of the UIAbility in the stage model.| | [Starting a UIAbility from the FA Model](start-uiability-from-fa.md)| Set **bundleName** and **abilityName** in the **want** parameter to the bundle name and ability name of the UIAbility in the stage model.|
| [Connecting to a ServiceExtensionAbility from the FA Model](bind-serviceextensionability-from-fa.md) | Set **bundleName** and **abilityName** in the **want** parameter to the bundle name and ability name of the ServiceExtensionAbility in the stage model.| | [Connecting to a ServiceExtensionAbility from the FA Model](bind-serviceextensionability-from-fa.md)| Set **bundleName** and **abilityName** in the **want** parameter to the bundle name and ability name of the ServiceExtensionAbility in the stage model.|
| [Accessing a DataShareExtensionAbility from the FA Model](access-datashareextensionability-from-fa.md) | No code modification is required. However, you need to understand the API compatibility of **DataShareHelper** and **DataAbilityHelper**.| | [Accessing a DataShareExtensionAbility from the FA Model](access-datashareextensionability-from-fa.md)| No code modification is required. However, you need to understand the API compatibility of **DataShareHelper** and **DataAbilityHelper**.|
| [Starting a PageAbility from the Stage Model](start-pageability-from-stage.md) | Set **bundleName** and **abilityName** in the **want** parameter to the bundle name and ability name of the PageAbility in the FA model.| | [Starting a PageAbility from the Stage Model](start-pageability-from-stage.md)| Set **bundleName** and **abilityName** in the **want** parameter to the bundle name and ability name of the PageAbility in the FA model.|
| [Connecting to a ServiceAbility from the Stage Model](bind-serviceability-from-stage.md) | Set **bundleName** and **abilityName** in the **want** parameter to the bundle name and ability name of the ServiceAbility in the FA model.| | [Connecting to a ServiceAbility from the Stage Model](bind-serviceability-from-stage.md)| Set **bundleName** and **abilityName** in the **want** parameter to the bundle name and ability name of the ServiceAbility in the FA model.|
| Accessing a DataAbility from the Stage Model | This type of access is not supported.| | Accessing a DataAbility from the Stage Model| This type of access is not supported.|
# featureAbility Switching # featureAbility Switching
| API in the FA Model| Corresponding d.ts File in the Stage Model| Corresponding API in the Stage Model| | API in the FA Model| Corresponding .d.ts File in the Stage Model| Corresponding API in the Stage Model|
| -------- | -------- | -------- | | -------- | -------- | -------- |
| [getWant(callback: AsyncCallback&lt;Want&gt;): void;](../reference/apis/js-apis-ability-featureAbility.md#featureabilitygetwant)<br>[getWant(): Promise&lt;Want&gt;;](../reference/apis/js-apis-ability-featureAbility.md#featureabilitygetwant-1) | \@ohos.app.ability.UIAbility.d.ts | [launchWant: Want;](../reference/apis/js-apis-app-ability-uiAbility.md#attributes)| | [getWant(callback: AsyncCallback&lt;Want&gt;): void;](../reference/apis/js-apis-ability-featureAbility.md#featureabilitygetwant)<br>[getWant(): Promise&lt;Want&gt;;](../reference/apis/js-apis-ability-featureAbility.md#featureabilitygetwant-1) | \@ohos.app.ability.UIAbility.d.ts | [launchWant: Want;](../reference/apis/js-apis-app-ability-uiAbility.md#attributes)|
| [startAbility(parameter: StartAbilityParameter, callback: AsyncCallback&lt;number&gt;): void;](../reference/apis/js-apis-ability-featureAbility.md#featureabilitystartability)<br>[startAbility(parameter: StartAbilityParameter): Promise&lt;number&gt;;](../reference/apis/js-apis-ability-featureAbility.md#featureabilitystartability-1) | application\UIAbilityContext.d.ts | [startAbility(want: Want, callback: AsyncCallback&lt;void&gt;): void;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstartability)<br>[startAbility(want: Want, options: StartOptions, callback: AsyncCallback&lt;void&gt;): void;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstartability-1)<br>[startAbility(want: Want, options?: StartOptions): Promise&lt;void&gt;;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstartability-2) | | [startAbility(parameter: StartAbilityParameter, callback: AsyncCallback&lt;number&gt;): void;](../reference/apis/js-apis-ability-featureAbility.md#featureabilitystartability)<br>[startAbility(parameter: StartAbilityParameter): Promise&lt;number&gt;;](../reference/apis/js-apis-ability-featureAbility.md#featureabilitystartability-1) | application\UIAbilityContext.d.ts | [startAbility(want: Want, callback: AsyncCallback&lt;void&gt;): void;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstartability)<br>[startAbility(want: Want, options: StartOptions, callback: AsyncCallback&lt;void&gt;): void;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstartability-1)<br>[startAbility(want: Want, options?: StartOptions): Promise&lt;void&gt;;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstartability-2) |
| [getContext(): Context;](../reference/apis/js-apis-ability-featureAbility.md#featureabilitygetcontext) | \@ohos.app.ability.UIAbility.d.ts | [context: UIAbilityContext;](../reference/apis/js-apis-app-ability-uiAbility.md#attributes)| | [getContext(): Context;](../reference/apis/js-apis-ability-featureAbility.md#featureabilitygetcontext) | \@ohos.app.ability.UIAbility.d.ts | [context: UIAbilityContext;](../reference/apis/js-apis-app-ability-uiAbility.md#attributes)|
| [startAbilityForResult(parameter: StartAbilityParameter, callback: AsyncCallback&lt;AbilityResult&gt;): void;](../reference/apis/js-apis-ability-featureAbility.md#featureabilitystartabilityforresult7)<br>[startAbilityForResult(parameter: StartAbilityParameter): Promise&lt;AbilityResult&gt;;](../reference/apis/js-apis-ability-featureAbility.md#featureabilitystartabilityforresult7-1) | application\UIAbilityContext.d.ts | [startAbilityForResult(want: Want, callback: AsyncCallback&lt;AbilityResult&gt;): void;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstartabilityforresult)<br>[startAbilityForResult(want: Want, options: StartOptions, callback: AsyncCallback&lt;AbilityResult&gt;): void;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstartabilityforresult-1)<br>[startAbilityForResult(want: Want, options?: StartOptions): Promise&lt;AbilityResult&gt;;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstartabilityforresult-2) | | [startAbilityForResult(parameter: StartAbilityParameter, callback: AsyncCallback&lt;AbilityResult&gt;): void;](../reference/apis/js-apis-ability-featureAbility.md#featureabilitystartabilityforresult7)<br>[startAbilityForResult(parameter: StartAbilityParameter): Promise&lt;AbilityResult&gt;;](../reference/apis/js-apis-ability-featureAbility.md#featureabilitystartabilityforresult7-1) | application\UIAbilityContext.d.ts | [startAbilityForResult(want: Want, callback: AsyncCallback&lt;AbilityResult&gt;): void;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstartabilityforresult)<br>[startAbilityForResult(want: Want, options: StartOptions, callback: AsyncCallback&lt;AbilityResult&gt;): void;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstartabilityforresult-1)<br>[startAbilityForResult(want: Want, options?: StartOptions): Promise&lt;AbilityResult&gt;;](../reference/apis/js-apis-inner-application-uiAbilityContext.md#abilitycontextstartabilityforresult-2) |
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
## When to Use ## When to Use
The main task of cross-device migration is to migrate the current task (including the page control status) of an application to the target device so that the task can continue on it. Cross-device migration supports the following functionalities: The main task of cross-device migration is to migrate the current task (including the page control status) of an application to the target device so that the task can continue on it. Cross-device migration supports the following features:
- Storage and restoration of custom data - Storage and restoration of custom data
...@@ -16,7 +16,8 @@ The main task of cross-device migration is to migrate the current task (includin ...@@ -16,7 +16,8 @@ The main task of cross-device migration is to migrate the current task (includin
The following figure shows the cross-device migration process. The following figure shows the cross-device migration process.
**Figure 1** Cross-device migration process **Figure 1** Cross-device migration process
![hop-cross-device-migration](figures/hop-cross-device-migration.png) ![hop-cross-device-migration](figures/hop-cross-device-migration.png)
...@@ -49,7 +50,7 @@ The table below describes the main APIs used for cross-device migration. For det ...@@ -49,7 +50,7 @@ The table below describes the main APIs used for cross-device migration. For det
1. Request the **ohos.permission.DISTRIBUTED_DATASYNC** permission. For details, see [Declaring Permissions in the Configuration File](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file). 1. Request the **ohos.permission.DISTRIBUTED_DATASYNC** permission. For details, see [Declaring Permissions in the Configuration File](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file).
2. Display a dialog box to ask authorization from the user when the application is started for the first time. For details, see [Requesting User Authorization](../security/accesstoken-guidelines.md#requesting-user-authorization). 2. Display a dialog box to ask for authorization from the user when the application is started for the first time. For details, see [Requesting User Authorization](../security/accesstoken-guidelines.md#requesting-user-authorization).
3. Configure the fields related to cross-device migration in the configuration file. 3. Configure the fields related to cross-device migration in the configuration file.
...@@ -79,7 +80,7 @@ The table below describes the main APIs used for cross-device migration. For det ...@@ -79,7 +80,7 @@ The table below describes the main APIs used for cross-device migration. For det
- Checking application compatibility: You can obtain the version number of the target application from **wantParam** and check the compatibility between the target application and the current application. - Checking application compatibility: You can obtain the version number of the target application from **wantParam** and check the compatibility between the target application and the current application.
- Making a migration decision: You can determine whether to support the migration based on the return value of **onContinue()**. For details about the return value, see [Available APIs](#available-apis). - Making a migration decision: You can determine whether to support the migration based on the return value of **onContinue()**. For details about the return values, see [Available APIs](#available-apis).
The sample code is as follows: The sample code is as follows:
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
## When to Use ## When to Use
Multi-device coordination involves the following scenarios: Multi-device collaboration involves the following scenarios:
- [Starting UIAbility or ServiceExtensionAbility Across Devices (No Data Returned)](#starting-uiability-or-serviceextensionability-across-devices-no-data-returned) - [Starting UIAbility or ServiceExtensionAbility Across Devices (No Data Returned)](#starting-uiability-or-serviceextensionability-across-devices-no-data-returned)
...@@ -18,13 +18,14 @@ Multi-device coordination involves the following scenarios: ...@@ -18,13 +18,14 @@ Multi-device coordination involves the following scenarios:
The figure below shows the multi-device collaboration process. The figure below shows the multi-device collaboration process.
**Figure 1** Multi-device collaboration process **Figure 1** Multi-device collaboration process
![hop-multi-device-collaboration](figures/hop-multi-device-collaboration.png) ![hop-multi-device-collaboration](figures/hop-multi-device-collaboration.png)
## Constraints ## Constraints
- Since multi-device collaboration task management is not available, you can obtain the device list by developing system applications. Access to third-party applications is not supported. - Since multi-device collaboration task management is not available, you can obtain the device list by developing system applications. Third-party applications cannot access the device list.
- Multi-device collaboration must comply with [Inter-Device Component Startup Rules](component-startup-rules.md#inter-device-component-startup-rules). - Multi-device collaboration must comply with [Inter-Device Component Startup Rules](component-startup-rules.md#inter-device-component-startup-rules).
...@@ -51,7 +52,7 @@ On device A, touch the **Start** button provided by the initiator application to ...@@ -51,7 +52,7 @@ On device A, touch the **Start** button provided by the initiator application to
1. Request the **ohos.permission.DISTRIBUTED_DATASYNC** permission. For details, see [Declaring Permissions in the Configuration File](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file). 1. Request the **ohos.permission.DISTRIBUTED_DATASYNC** permission. For details, see [Declaring Permissions in the Configuration File](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file).
2. Display a dialog box to ask authorization from the user when the application is started for the first time. For details, see [Requesting User Authorization](../security/accesstoken-guidelines.md#requesting-user-authorization). 2. Display a dialog box to ask for authorization from the user when the application is started for the first time. For details, see [Requesting User Authorization](../security/accesstoken-guidelines.md#requesting-user-authorization).
3. Obtain the device ID of the target device. 3. Obtain the device ID of the target device.
...@@ -119,7 +120,7 @@ On device A, touch the **Start** button provided by the initiator application to ...@@ -119,7 +120,7 @@ On device A, touch the **Start** button provided by the initiator application to
## Starting UIAbility Across Devices (Data Returned) ## Starting UIAbility Across Devices (Data Returned)
On device A, touch the **Start** button provided by the initiator application to start a specified UIAbility on device B. When the UIAbility on device B exits, a value is sent back to the initiator application. On device A, touch the **Start** button provided by the initiator application to start a specified UIAbility on device B. When the UIAbility on device B exits, a value is returned to the initiator application.
### Available APIs ### Available APIs
...@@ -137,7 +138,7 @@ On device A, touch the **Start** button provided by the initiator application to ...@@ -137,7 +138,7 @@ On device A, touch the **Start** button provided by the initiator application to
1. Request the **ohos.permission.DISTRIBUTED_DATASYNC** permission. For details, see [Declaring Permissions in the Configuration File](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file). 1. Request the **ohos.permission.DISTRIBUTED_DATASYNC** permission. For details, see [Declaring Permissions in the Configuration File](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file).
2. Display a dialog box to ask authorization from the user when the application is started for the first time. For details, see [Requesting User Authorization](../security/accesstoken-guidelines.md#requesting-user-authorization). 2. Display a dialog box to ask for authorization from the user when the application is started for the first time. For details, see [Requesting User Authorization](../security/accesstoken-guidelines.md#requesting-user-authorization).
3. Set the target component parameters on the initiator, and call **startAbilityForResult()** to start the target UIAbility. **data** in the asynchronous callback is used to receive the information returned by the target UIAbility to the initiator UIAbility after the target UIAbility terminates itself. For details about how to implement **getRemoteDeviceId()**, see [Starting UIAbility or ServiceExtensionAbility Across Devices (No Data Returned)](#starting-uiability-or-serviceextensionability-across-devices-no-data-returned). 3. Set the target component parameters on the initiator, and call **startAbilityForResult()** to start the target UIAbility. **data** in the asynchronous callback is used to receive the information returned by the target UIAbility to the initiator UIAbility after the target UIAbility terminates itself. For details about how to implement **getRemoteDeviceId()**, see [Starting UIAbility or ServiceExtensionAbility Across Devices (No Data Returned)](#starting-uiability-or-serviceextensionability-across-devices-no-data-returned).
...@@ -156,7 +157,7 @@ On device A, touch the **Start** button provided by the initiator application to ...@@ -156,7 +157,7 @@ On device A, touch the **Start** button provided by the initiator application to
}) })
``` ```
4. After the UIAbility task at the target device is complete, call **terminateSelfWithResult()** to return the data to the initiator UIAbility. 4. After the UIAbility task on the target device is complete, call **terminateSelfWithResult()** to return the data to the initiator UIAbility.
```ts ```ts
const RESULT_CODE: number = 1001; const RESULT_CODE: number = 1001;
...@@ -214,7 +215,7 @@ A system application can connect to a service on another device by calling [conn ...@@ -214,7 +215,7 @@ A system application can connect to a service on another device by calling [conn
1. Request the **ohos.permission.DISTRIBUTED_DATASYNC** permission. For details, see [Declaring Permissions in the Configuration File](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file). 1. Request the **ohos.permission.DISTRIBUTED_DATASYNC** permission. For details, see [Declaring Permissions in the Configuration File](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file).
2. Display a dialog box to ask authorization from the user when the application is started for the first time. For details, see [Requesting User Authorization](../security/accesstoken-guidelines.md#requesting-user-authorization). 2. Display a dialog box to ask for authorization from the user when the application is started for the first time. For details, see [Requesting User Authorization](../security/accesstoken-guidelines.md#requesting-user-authorization).
3. (Optional) [Implement a background service](serviceextensionability.md#implementing-a-background-service). Perform this operation only if no background service is available. 3. (Optional) [Implement a background service](serviceextensionability.md#implementing-a-background-service). Perform this operation only if no background service is available.
...@@ -223,7 +224,7 @@ A system application can connect to a service on another device by calling [conn ...@@ -223,7 +224,7 @@ A system application can connect to a service on another device by calling [conn
- Set the target component parameters, including the target device ID, bundle name, and ability name. - Set the target component parameters, including the target device ID, bundle name, and ability name.
- Call **connectServiceExtensionAbility** to initiate a connection. - Call **connectServiceExtensionAbility** to initiate a connection.
- Receive the service handle returned by the target device when the connection is successful. - Receive the service handle returned by the target device when the connection is successful.
- Perform cross-device invoking and obtain the result returned by the target service. - Perform cross-device call and obtain the result returned by the target service.
```ts ```ts
import rpc from '@ohos.rpc'; import rpc from '@ohos.rpc';
...@@ -311,7 +312,7 @@ The following describes how to implement multi-device collaboration through cros ...@@ -311,7 +312,7 @@ The following describes how to implement multi-device collaboration through cros
1. Request the **ohos.permission.DISTRIBUTED_DATASYNC** permission. For details, see [Declaring Permissions in the Configuration File](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file). 1. Request the **ohos.permission.DISTRIBUTED_DATASYNC** permission. For details, see [Declaring Permissions in the Configuration File](../security/accesstoken-guidelines.md#declaring-permissions-in-the-configuration-file).
2. Display a dialog box to ask authorization from the user when the application is started for the first time. For details, see [Requesting User Authorization](../security/accesstoken-guidelines.md#requesting-user-authorization). 2. Display a dialog box to ask for authorization from the user when the application is started for the first time. For details, see [Requesting User Authorization](../security/accesstoken-guidelines.md#requesting-user-authorization).
3. Create the CalleeAbility. 3. Create the CalleeAbility.
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
## When to Use ## When to Use
As the all-scenario, multi-device lifestyle becomes popular, users have an increasing number of devices. Each device provides users with what they need in a certain scenario. For example, watches allow users to view information in a timely manner, and smart TVs bring them an immersive watching experience. However, each device has its limitation, for example, typing text on a smart TV is frustrating as it is much more difficult than on a mobile device. If multiple devices can sense each other through a distributed OS and together form a super device, the strengths of each device can be fully exerted to provide a more natural and smoother distributed experience for users. As the all-scenario, multi-device lifestyle becomes popular, users have an increasing number of devices. Each device provides users with what they need in a certain scenario. For example, watches allow users to view information in a timely manner, and smart TVs bring them an immersive watching experience. However, each device has its limitations, for example, typing text on a smart TV is frustrating as it is much more difficult than on a mobile device. If multiple devices can sense each other through a distributed OS and together form a super device, the strengths of each device can be fully exerted to provide a more natural and smoother distributed experience for users.
In OpenHarmony, distributed operations across devices are called continuation (previously named hopping), which is further classified into [cross-device migration](hop-cross-device-migration.md) and [multi-device collaboration](hop-multi-device-collaboration.md). To implement continuation, cross-device interaction capabilities of application components are required. Currently, these capabilities are open only to system applications. In OpenHarmony, distributed operations across devices are called continuation (previously named hopping), which is further classified into [cross-device migration](hop-cross-device-migration.md) and [multi-device collaboration](hop-multi-device-collaboration.md). To implement continuation, cross-device interaction capabilities of application components are required. Currently, these capabilities are open only to system applications.
...@@ -20,7 +20,7 @@ In OpenHarmony, distributed operations across devices are called continuation (p ...@@ -20,7 +20,7 @@ In OpenHarmony, distributed operations across devices are called continuation (p
- **Multi-device collaboration** - **Multi-device collaboration**
Multi-device collaboration enables collaboration between multiple devices, providing users with more efficient and immersive experience than with a single device. A typical multi-device collaboration scenario is as follows: Application A on the tablet is used as the answer board, and application B on the smart TV is used for live broadcast, delivering a better online class experience. From the perspective of application development, multi-device collaboration enables different UIAbility or ServiceExtensionAbility components to run simultaneously or alternately on multiple devices to provide a complete service, or enables the same UIAbility and ServiceExtensionAbility component to run simultaneously on multiple devices to provide a complete service. Multi-device collaboration provides users with more efficient and immersive experience than with a single device. A typical multi-device collaboration scenario is as follows: Application A on the tablet is used as the answer board, and application B on the smart TV is used for live broadcast, delivering a better online class experience. From the perspective of application development, multi-device collaboration enables different UIAbility or ServiceExtensionAbility components to run simultaneously or alternately on multiple devices to provide a complete service, or enables the same UIAbility and ServiceExtensionAbility component to run simultaneously on multiple devices to provide a complete service.
## Continuation Architecture ## Continuation Architecture
...@@ -35,9 +35,9 @@ OpenHarmony provides a set of APIs for you to implement continuation in your app ...@@ -35,9 +35,9 @@ OpenHarmony provides a set of APIs for you to implement continuation in your app
The following figure shows the continuation architecture. The following figure shows the continuation architecture.
**Figure 1** Continuation architecture **Figure 1** Continuation architecture
![hop-structure](figures/hop-structure.png) ![hop-structure](figures/hop-structure.png)
- Cross-device migration task management: The initiator accepts a migration request from the user, provides a migration entry, and displays the migration result. (This capability is unavailable yet.) - Cross-device migration task management: The initiator accepts a migration request from the user, provides a migration entry, and displays the migration result. (This capability is unavailable yet.)
...@@ -47,4 +47,4 @@ The following figure shows the continuation architecture. ...@@ -47,4 +47,4 @@ The following figure shows the continuation architecture.
- Distributed security authentication: provides an E2E encrypted channel for cross-device transmission between applications to ensure that the right person uses the right data through the right device. - Distributed security authentication: provides an E2E encrypted channel for cross-device transmission between applications to ensure that the right person uses the right data through the right device.
- DSoftBus: functions as a unified communication base for a wide range of devices such as tablets, wearables, and smart TVs, and enables unified distributed communication between these devices. - DSoftBus: functions as a unified communication base for a wide range of devices, such as tablets, wearables, and smart TVs, and enables unified distributed communication between these devices.
# LifecycleApp Switching # LifecycleApp Switching
| API in the FA Model| Corresponding d.ts File in the Stage Model| Corresponding API in the Stage Model| | API in the FA Model| Corresponding .d.ts File in the Stage Model| Corresponding API in the Stage Model|
| -------- | -------- | -------- | | -------- | -------- | -------- |
| onShow?(): void; | \@ohos.window.d.ts | [on(eventType: 'windowStageEvent', callback: Callback&lt;WindowStageEventType&gt;): void;](../reference/apis/js-apis-window.md#onwindowstageevent9)<br>Listens for the switching to the [foreground](../reference/apis/js-apis-window.md#windowstageeventtype9).| | onShow?(): void; | \@ohos.window.d.ts | [on(eventType: 'windowStageEvent', callback: Callback&lt;WindowStageEventType&gt;): void;](../reference/apis/js-apis-window.md#onwindowstageevent9)<br>Listens for the switching to the [foreground](../reference/apis/js-apis-window.md#windowstageeventtype9).|
| onHide?(): void; | \@ohos.window.d.ts | [on(eventType: 'windowStageEvent', callback: Callback&lt;WindowStageEventType&gt;): void;](../reference/apis/js-apis-window.md#onwindowstageevent9)<br>Listens for the switching to the [background](../reference/apis/js-apis-window.md#windowstageeventtype9).| | onHide?(): void; | \@ohos.window.d.ts | [on(eventType: 'windowStageEvent', callback: Callback&lt;WindowStageEventType&gt;): void;](../reference/apis/js-apis-window.md#onwindowstageevent9)<br>Listens for the switching to the [background](../reference/apis/js-apis-window.md#windowstageeventtype9).|
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
| onRestoreData?(data: Object): void; | \@ohos.app.ability.UIAbility.d.ts | [onCreate(want: Want, param: AbilityConstant.LaunchParam): void;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncreate)<br>[onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant)<br>In multiton or singleton mode, the target ability completes data restoration in the **onCreate()** callback. In the callback, **launchParam.launchReason** is used to determine whether it is a continuation-based launch scenario. If it is, the data saved before continuation can be obtained from the **want** parameter.| | onRestoreData?(data: Object): void; | \@ohos.app.ability.UIAbility.d.ts | [onCreate(want: Want, param: AbilityConstant.LaunchParam): void;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncreate)<br>[onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant)<br>In multiton or singleton mode, the target ability completes data restoration in the **onCreate()** callback. In the callback, **launchParam.launchReason** is used to determine whether it is a continuation-based launch scenario. If it is, the data saved before continuation can be obtained from the **want** parameter.|
| onRemoteTerminated?(): void; | application\ContinueCallback.d.ts | [onContinueDone(result: number): void;](../reference/apis/js-apis-distributedMissionManager.md#continuecallback) | | onRemoteTerminated?(): void; | application\ContinueCallback.d.ts | [onContinueDone(result: number): void;](../reference/apis/js-apis-distributedMissionManager.md#continuecallback) |
| onSaveAbilityState?(outState: PacMap): void; | \@ohos.app.ability.UIAbility.d.ts | [onSaveState(reason: AbilityConstant.StateType, wantParam : {[key: string]: any}): AbilityConstant.OnSaveResult;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonsavestate) | | onSaveAbilityState?(outState: PacMap): void; | \@ohos.app.ability.UIAbility.d.ts | [onSaveState(reason: AbilityConstant.StateType, wantParam : {[key: string]: any}): AbilityConstant.OnSaveResult;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonsavestate) |
| onRestoreAbilityState?(inState: PacMap): void; | \@ohos.app.ability.UIAbility.d.ts | [onCreate(want: Want, param: AbilityConstant.LaunchParam): void;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncreate)<br>After the application is restarted, the **onCreate()** callback is triggered. In the callback, **launchParam.launchReason** is used to determine whether it is a self-recovery scenario. If it is, the data saved before the restart can be obtained from the **want** parameter.| | onRestoreAbilityState?(inState: PacMap): void; | \@ohos.app.ability.UIAbility.d.ts | [onCreate(want: Want, param: AbilityConstant.LaunchParam): void;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityoncreate)<br>After an application is restarted, the **onCreate()** callback is triggered. In the callback, **launchParam.launchReason** is used to determine whether it is a self-recovery scenario. If it is, the data saved before the restart can be obtained from the **want** parameter.|
| onInactive?(): void; | \@ohos.app.ability.UIAbility.d.ts | [onBackground(): void;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonbackground) | | onInactive?(): void; | \@ohos.app.ability.UIAbility.d.ts | [onBackground(): void;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonbackground) |
| onActive?(): void; | \@ohos.app.ability.UIAbility.d.ts | [onForeground(): void;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonforeground) | | onActive?(): void; | \@ohos.app.ability.UIAbility.d.ts | [onForeground(): void;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonforeground) |
| onNewWant?(want: Want): void; | \@ohos.app.ability.UIAbility.d.ts | [onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant) | | onNewWant?(want: Want): void; | \@ohos.app.ability.UIAbility.d.ts | [onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void;](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant) |
......
# LifecycleData Switching # LifecycleData Switching
| API in the FA Model| Corresponding d.ts File in the Stage Model| Corresponding API in the Stage Model| | API in the FA Model| Corresponding .d.ts File in the Stage Model| Corresponding API in the Stage Model|
| -------- | -------- | -------- | | -------- | -------- | -------- |
| update?(uri: string, valueBucket: rdb.ValuesBucket, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback&lt;number&gt;): void; | \@ohos.application.DataShareExtensionAbility.d.ts | [update?(uri: string, predicates: dataSharePredicates.DataSharePredicates, valueBucket: ValuesBucket, callback: AsyncCallback&lt;number&gt;): void;](../reference/apis/js-apis-application-dataShareExtensionAbility.md#update) | | update?(uri: string, valueBucket: rdb.ValuesBucket, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback&lt;number&gt;): void; | \@ohos.application.DataShareExtensionAbility.d.ts | [update?(uri: string, predicates: dataSharePredicates.DataSharePredicates, valueBucket: ValuesBucket, callback: AsyncCallback&lt;number&gt;): void;](../reference/apis/js-apis-application-dataShareExtensionAbility.md#update) |
| query?(uri: string, columns: Array&lt;string&gt;, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback&lt;ResultSet&gt;): void; | \@ohos.application.DataShareExtensionAbility.d.ts | [query?(uri: string, predicates: dataSharePredicates.DataSharePredicates, columns: Array&lt;string&gt;, callback: AsyncCallback&lt;Object&gt;): void;](../reference/apis/js-apis-application-dataShareExtensionAbility.md#query) | | query?(uri: string, columns: Array&lt;string&gt;, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback&lt;ResultSet&gt;): void; | \@ohos.application.DataShareExtensionAbility.d.ts | [query?(uri: string, predicates: dataSharePredicates.DataSharePredicates, columns: Array&lt;string&gt;, callback: AsyncCallback&lt;Object&gt;): void;](../reference/apis/js-apis-application-dataShareExtensionAbility.md#query) |
......
# LifecycleForm Switching # LifecycleForm Switching
| API in the FA Model| Corresponding d.ts File in the Stage Model| Corresponding API in the Stage Model| | API in the FA Model| Corresponding .d.ts File in the Stage Model| Corresponding API in the Stage Model|
| -------- | -------- | -------- | | -------- | -------- | -------- |
| onCreate?(want: Want): formBindingData.FormBindingData; | \@ohos.app.form.FormExtensionAbility.d.ts | [onAddForm(want: Want): formBindingData.FormBindingData;](../reference/apis/js-apis-app-form-formExtensionAbility.md#onaddform) | | onCreate?(want: Want): formBindingData.FormBindingData; | \@ohos.app.form.FormExtensionAbility.d.ts | [onAddForm(want: Want): formBindingData.FormBindingData;](../reference/apis/js-apis-app-form-formExtensionAbility.md#onaddform) |
| onCastToNormal?(formId: string): void; | \@ohos.app.form.FormExtensionAbility.d.ts | [onCastToNormalForm(formId: string): void;](../reference/apis/js-apis-app-form-formExtensionAbility.md#oncasttonormalform) | | onCastToNormal?(formId: string): void; | \@ohos.app.form.FormExtensionAbility.d.ts | [onCastToNormalForm(formId: string): void;](../reference/apis/js-apis-app-form-formExtensionAbility.md#oncasttonormalform) |
......
# LifecycleService Switching # LifecycleService Switching
| API in the FA Model| Corresponding d.ts File in the Stage Model| Corresponding API in the Stage Model| | API in the FA Model| Corresponding .d.ts File in the Stage Model| Corresponding API in the Stage Model|
| -------- | -------- | -------- | | -------- | -------- | -------- |
| onStart?(): void; | \@ohos.app.ability.ServiceExtensionAbility.d.ts | [onCreate(want: Want): void;](../reference/apis/js-apis-app-ability-serviceExtensionAbility.md#serviceextensionabilityoncreate) | | onStart?(): void; | \@ohos.app.ability.ServiceExtensionAbility.d.ts | [onCreate(want: Want): void;](../reference/apis/js-apis-app-ability-serviceExtensionAbility.md#serviceextensionabilityoncreate) |
| onCommand?(want: Want, startId: number): void; | \@ohos.app.ability.ServiceExtensionAbility.d.ts | [onRequest(want: Want, startId: number): void;](../reference/apis/js-apis-app-ability-serviceExtensionAbility.md#serviceextensionabilityonrequest) | | | onCommand?(want: Want, startId: number): void; | \@ohos.app.ability.ServiceExtensionAbility.d.ts | [onRequest(want: Want, startId: number): void;](../reference/apis/js-apis-app-ability-serviceExtensionAbility.md#serviceextensionabilityonrequest) | |
......
# mediaLibrary Switching # mediaLibrary Switching
| API in the FA Model| Corresponding d.ts File in the Stage Model| Corresponding API in the Stage Model| | API in the FA Model| Corresponding .d.ts File in the Stage Model| Corresponding API in the Stage Model|
| -------- | -------- | -------- | | -------- | -------- | -------- |
| [getMediaLibrary(): MediaLibrary;](../reference/apis/js-apis-medialibrary.md#medialibrarygetmedialibrary) | \@ohos.multimedia.mediaLibrary.d.ts | [getMediaLibrary(context: Context): MediaLibrary;](../reference/apis/js-apis-medialibrary.md#medialibrarygetmedialibrary8) | | [getMediaLibrary(): MediaLibrary;](../reference/apis/js-apis-medialibrary.md#medialibrarygetmedialibrary) | \@ohos.multimedia.mediaLibrary.d.ts | [getMediaLibrary(context: Context): MediaLibrary;](../reference/apis/js-apis-medialibrary.md#medialibrarygetmedialibrary8) |
...@@ -17,11 +17,13 @@ This document describes the following operations: ...@@ -17,11 +17,13 @@ This document describes the following operations:
## Setting a Mission Snapshot Icon (for System Applications Only) ## Setting a Mission Snapshot Icon (for System Applications Only)
Call [UIAbilityContext.setMissionIcon()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextsetmissionicon) to set the icon of a mission snapshot. The icon is an object of the [PixelMap](../reference/apis/js-apis-image.md#pixelmap7) type. For details about how to obtain the context, see [Obtaining the Context of UIAbility](uiability-usage.md#obtaining-the-context-of-uiability). Call [UIAbilityContext.setMissionIcon()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextsetmissionicon) to set the icon of a mission snapshot. For details about how to obtain the context, see [Obtaining the Context of UIAbility](uiability-usage.md#obtaining-the-context-of-uiability). For details about how to obtain the PixelMap information in the example, see [Image Decoding](../media/image-decoding.md).
```ts ```ts
let imagePixelMap: PixelMap = undefined; // Obtain the PixelMap information. let context = ...; // UIAbilityContext
let pixelMap: PixelMap =...; // PixelMap information of the image.
context.setMissionIcon(imagePixelMap, (err) => { context.setMissionIcon(pixelMap, (err) => {
if (err.code) { if (err.code) {
console.error(`Failed to set mission icon. Code is ${err.code}, message is ${err.message}`); console.error(`Failed to set mission icon. Code is ${err.code}, message is ${err.message}`);
} }
...@@ -31,7 +33,6 @@ context.setMissionIcon(imagePixelMap, (err) => { ...@@ -31,7 +33,6 @@ context.setMissionIcon(imagePixelMap, (err) => {
The display effect is shown below. The display effect is shown below.
Figure 2 Mission snapshot icon Figure 2 Mission snapshot icon
![](figures/mission-set-task-snapshot-icon.png) ![](figures/mission-set-task-snapshot-icon.png)
## Setting a Mission Snapshot Name ## Setting a Mission Snapshot Name
...@@ -39,7 +40,9 @@ Figure 2 Mission snapshot icon ...@@ -39,7 +40,9 @@ Figure 2 Mission snapshot icon
Call [UIAbilityContext.setMissionLabel()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextsetmissionlabel) to set the name of a mission snapshot. Call [UIAbilityContext.setMissionLabel()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextsetmissionlabel) to set the name of a mission snapshot.
```ts ```ts
this.context.setMissionLabel('test').then(() => { let context = ...; // UIAbilityContext
context.setMissionLabel('test').then(() => {
console.info('Succeeded in seting mission label.'); console.info('Succeeded in seting mission label.');
}).catch((err) => { }).catch((err) => {
console.error(`Failed to set mission label. Code is ${err.code}, message is ${err.message}`); console.error(`Failed to set mission label. Code is ${err.code}, message is ${err.message}`);
...@@ -49,5 +52,4 @@ this.context.setMissionLabel('test').then(() => { ...@@ -49,5 +52,4 @@ this.context.setMissionLabel('test').then(() => {
The display effect is shown below. The display effect is shown below.
Figure 3 Mission snapshot name Figure 3 Mission snapshot name
![](figures/mission-set-task-snapshot-label.png) ![](figures/mission-set-task-snapshot-label.png)
...@@ -5,19 +5,23 @@ Perform the following operations to switch a declarative paradigm-based applicat ...@@ -5,19 +5,23 @@ Perform the following operations to switch a declarative paradigm-based applicat
- Project switch: Create an application project of the stage model. - Project switch: Create an application project of the stage model.
![model-switch-overview1](figures/model-switch-overview1.png) ![model-switch-overview1](figures/model-switch-overview1.png)
- [Configuration file switch](configuration-file-diff.md): Switch **config.json** to **app.json5** and **module.json5**. - [Configuration file switch](configuration-file-diff.md): Switch **config.json** to **app.json5** and **module.json5**.
![model-switch-overview2](figures/model-switch-overview2.png) ![model-switch-overview2](figures/model-switch-overview2.png)
- [Component switch](pageability-switch.md): Switch the PageAbility, ServiceAbility, and DataAbility components of the FA model to the UIAbility and ExtensionAbility components of the stage model. The figure below shows only the switching from PageAbility to UIAbility. The left part is the FA model, and **app.ets** is the PageAbility component. The right part is the stage model, and **EntryAbility.ts** is the UIAbility component. - [Component switch](pageability-switch.md): Switch the PageAbility, ServiceAbility, and DataAbility components of the FA model to the UIAbility and ExtensionAbility components of the stage model. The figure below shows only the switching from PageAbility to UIAbility. The left part is the FA model, and **app.ets** is the PageAbility component. The right part is the stage model, and **EntryAbility.ts** is the UIAbility component.
![model-switch-overview3](figures/model-switch-overview3.png) ![model-switch-overview3](figures/model-switch-overview3.png)
- [Widget switch](widget-switch.md): Switch the FormAbility component of the FA model to the FormExtensionAbility component of the stage model. In the figure below, **Service Widget** is FormAbility in the FA model and FormExtensionAbility in the stage model. - [Widget switch](widget-switch.md): Switch the FormAbility component of the FA model to the FormExtensionAbility component of the stage model. In the figure below, **Service Widget** is FormAbility in the FA model and FormExtensionAbility in the stage model.
![model-switch-overview4](figures/model-switch-overview4.png) ![model-switch-overview4](figures/model-switch-overview4.png)
![model-switch-overview5](figures/model-switch-overview5.png) ![model-switch-overview5](figures/model-switch-overview5.png)
- [API switch](api-switch-overview.md): Switch the APIs with the **FAModelOnly** tag used in the FA model to the recommended APIs in the stage model. - [API switch](api-switch-overview.md): Switch the APIs with the **FAModelOnly** tag used in the FA model to the recommended APIs in the stage model.
![model-switch-overview6](figures/model-switch-overview6.png) ![model-switch-overview6](figures/model-switch-overview6.png)
# Switching of module # Switching of module
When switching an application from the FA model to the stage model, you must migrate the configurations under the **module** tag in the **config.json** file to the **module** tag in the **module.json5** file. When switching an application from the FA model to the stage model, migrate the configurations under **module** in the **config.json** file to **module** in the **module.json5** file.
**Table 1** module comparison **Table 1** module comparison
...@@ -60,7 +60,7 @@ When switching an application from the FA model to the stage model, you must mig ...@@ -60,7 +60,7 @@ When switching an application from the FA model to the stage model, you must mig
| deviceCapability | Device capabilities required to run the ability.| / | This configuration is not supported in the stage model.| | deviceCapability | Device capabilities required to run the ability.| / | This configuration is not supported in the stage model.|
| metaData | Metadata of the ability.| metadata | For details, see Table 2.| | metaData | Metadata of the ability.| metadata | For details, see Table 2.|
| type | Ability type.| / | This configuration is not supported in the stage model.| | type | Ability type.| / | This configuration is not supported in the stage model.|
| grantPermission | Whether permissions can be granted for any data in the ability.| / | The stage model does not support such a configuration under **abilities**.| | grantPermission | Whether permissions can be granted to any data in the ability.| / | The stage model does not support such a configuration under **abilities**.|
| readPermission | Permission required for reading data in the ability. This field applies only to the ability using the Data template.| / | In the stage model, this configuration is available under **extensionAbilities**, but not **abilities**.| | readPermission | Permission required for reading data in the ability. This field applies only to the ability using the Data template.| / | In the stage model, this configuration is available under **extensionAbilities**, but not **abilities**.|
| writePermission | Permission required for writing data to the ability.| / | In the stage model, this configuration is available under **extensionAbilities**, but not **abilities**.| | writePermission | Permission required for writing data to the ability.| / | In the stage model, this configuration is available under **extensionAbilities**, but not **abilities**.|
| configChanges | System configurations that the ability concerns.| / | This configuration is not supported in the stage model.| | configChanges | System configurations that the ability concerns.| / | This configuration is not supported in the stage model.|
......
...@@ -27,7 +27,7 @@ The PageAbility lifecycle is basically the same as the UIAbility lifecycle. The ...@@ -27,7 +27,7 @@ The PageAbility lifecycle is basically the same as the UIAbility lifecycle. The
3. Adjust the migrated code, since the methods of loading pages are different. 3. Adjust the migrated code, since the methods of loading pages are different.
- In the FA model, you can configure the page to be loaded by setting page information in **config.json**. - In the FA model, you can configure the page to be loaded by setting page information in **config.json**.
- In the stage model, you must call **windowStage.loadContent** in the **onWindowStageCreate** callback to load a page. - In the stage model, call **windowStage.loadContent** in the **onWindowStageCreate** callback to load a page.
For example, to load the **pages/Index** page after the ability is started, use the following code in the **config.json** file in the FA model: For example, to load the **pages/Index** page after the ability is started, use the following code in the **config.json** file in the FA model:
......
# particleAbility Switching # particleAbility Switching
| API in the FA Model| Corresponding d.ts File in the Stage Model| Corresponding API in the Stage Model| | API in the FA Model| Corresponding .d.ts File in the Stage Model| Corresponding API in the Stage Model|
| -------- | -------- | -------- | | -------- | -------- | -------- |
| [startAbility(parameter: StartAbilityParameter, callback: AsyncCallback&lt;number&gt;): void;](../reference/apis/js-apis-ability-particleAbility.md#particleabilitystartability)<br>[startAbility(parameter: StartAbilityParameter): Promise&lt;number&gt;;](../reference/apis/js-apis-ability-particleAbility.md#particleabilitystartability-1) | application\ServiceExtensionContext.d.ts | [startAbility(want: Want, callback: AsyncCallback&lt;void&gt;): void;](../reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextstartability)<br>[startAbility(want: Want, options: StartOptions, callback: AsyncCallback&lt;void&gt;): void;](../reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextstartability-2)<br>[startAbility(want: Want, options?: StartOptions): Promise&lt;void&gt;;](../reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextstartability-1)<br>[startServiceExtensionAbility(want: Want, callback: AsyncCallback&lt;void&gt;): void;](../reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextstartserviceextensionability)<br>[startServiceExtensionAbility(want: Want): Promise&lt;void&gt;;](../reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextstartserviceextensionability-1) | | [startAbility(parameter: StartAbilityParameter, callback: AsyncCallback&lt;number&gt;): void;](../reference/apis/js-apis-ability-particleAbility.md#particleabilitystartability)<br>[startAbility(parameter: StartAbilityParameter): Promise&lt;number&gt;;](../reference/apis/js-apis-ability-particleAbility.md#particleabilitystartability-1) | application\ServiceExtensionContext.d.ts | [startAbility(want: Want, callback: AsyncCallback&lt;void&gt;): void;](../reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextstartability)<br>[startAbility(want: Want, options: StartOptions, callback: AsyncCallback&lt;void&gt;): void;](../reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextstartability-2)<br>[startAbility(want: Want, options?: StartOptions): Promise&lt;void&gt;;](../reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextstartability-1)<br>[startServiceExtensionAbility(want: Want, callback: AsyncCallback&lt;void&gt;): void;](../reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextstartserviceextensionability)<br>[startServiceExtensionAbility(want: Want): Promise&lt;void&gt;;](../reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextstartserviceextensionability-1) |
| [terminateSelf(callback: AsyncCallback&lt;void&gt;): void;](../reference/apis/js-apis-ability-particleAbility.md#particleabilityterminateself)<br>[terminateSelf(): Promise&lt;void&gt;;](../reference/apis/js-apis-ability-particleAbility.md#particleabilityterminateself-1) | application\ServiceExtensionContext.d.ts | [terminateSelf(callback: AsyncCallback&lt;void&gt;): void;](../reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextterminateself)<br>[terminateSelf(): Promise&lt;void&gt;;](../reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextterminateself-1) | | [terminateSelf(callback: AsyncCallback&lt;void&gt;): void;](../reference/apis/js-apis-ability-particleAbility.md#particleabilityterminateself)<br>[terminateSelf(): Promise&lt;void&gt;;](../reference/apis/js-apis-ability-particleAbility.md#particleabilityterminateself-1) | application\ServiceExtensionContext.d.ts | [terminateSelf(callback: AsyncCallback&lt;void&gt;): void;](../reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextterminateself)<br>[terminateSelf(): Promise&lt;void&gt;;](../reference/apis/js-apis-inner-application-serviceExtensionContext.md#serviceextensioncontextterminateself-1) |
...@@ -10,3 +10,5 @@ ...@@ -10,3 +10,5 @@
| [acquireDataAbilityHelper(uri: string): DataAbilityHelper;](../reference/apis/js-apis-ability-particleAbility.md#particleabilityacquiredataabilityhelper) | \@ohos.data.dataShare.d.ts<br>[\@ohos.data.fileAccess.d.ts | [createDataShareHelper(context: Context, uri: string, callback: AsyncCallback&lt;DataShareHelper&gt;): void;](../reference/apis/js-apis-data-dataShare.md#datasharecreatedatasharehelper)<br>[createDataShareHelper(context: Context, uri: string): Promise&lt;DataShareHelper&gt;;](../reference/apis/js-apis-data-dataShare.md#datasharecreatedatasharehelper-1)<br>[createFileAccessHelper(context: Context): FileAccessHelper;](../reference/apis/js-apis-fileAccess.md#fileaccesscreatefileaccesshelper-1)<br>[createFileAccessHelper(context: Context, wants: Array&lt;Want&gt;): FileAccessHelper;](../reference/apis/js-apis-fileAccess.md#fileaccesscreatefileaccesshelper) | | [acquireDataAbilityHelper(uri: string): DataAbilityHelper;](../reference/apis/js-apis-ability-particleAbility.md#particleabilityacquiredataabilityhelper) | \@ohos.data.dataShare.d.ts<br>[\@ohos.data.fileAccess.d.ts | [createDataShareHelper(context: Context, uri: string, callback: AsyncCallback&lt;DataShareHelper&gt;): void;](../reference/apis/js-apis-data-dataShare.md#datasharecreatedatasharehelper)<br>[createDataShareHelper(context: Context, uri: string): Promise&lt;DataShareHelper&gt;;](../reference/apis/js-apis-data-dataShare.md#datasharecreatedatasharehelper-1)<br>[createFileAccessHelper(context: Context): FileAccessHelper;](../reference/apis/js-apis-fileAccess.md#fileaccesscreatefileaccesshelper-1)<br>[createFileAccessHelper(context: Context, wants: Array&lt;Want&gt;): FileAccessHelper;](../reference/apis/js-apis-fileAccess.md#fileaccesscreatefileaccesshelper) |
| [startBackgroundRunning(id: number, request: NotificationRequest, callback: AsyncCallback&lt;void&gt;): void;](../reference/apis/js-apis-ability-particleAbility.md#particleabilitystartbackgroundrunning)<br>[startBackgroundRunning(id: number, request: NotificationRequest): Promise&lt;void&gt;;](../reference/apis/js-apis-ability-particleAbility.md#particleabilitystartbackgroundrunning-1) | \@ohos.resourceschedule.backgroundTaskManager.d.ts | [startBackgroundRunning(context: Context, bgMode: BackgroundMode, wantAgent: WantAgent, callback: AsyncCallback): void;](../reference/apis/js-apis-resourceschedule-backgroundTaskManager.md#backgroundtaskmanagerstartbackgroundrunningcallback)<br>[startBackgroundRunning(context: Context, bgMode: BackgroundMode, wantAgent: WantAgent): Promise&lt;void&gt;;](../reference/apis/js-apis-resourceschedule-backgroundTaskManager.md#backgroundtaskmanagerstartbackgroundrunningpromise) | | [startBackgroundRunning(id: number, request: NotificationRequest, callback: AsyncCallback&lt;void&gt;): void;](../reference/apis/js-apis-ability-particleAbility.md#particleabilitystartbackgroundrunning)<br>[startBackgroundRunning(id: number, request: NotificationRequest): Promise&lt;void&gt;;](../reference/apis/js-apis-ability-particleAbility.md#particleabilitystartbackgroundrunning-1) | \@ohos.resourceschedule.backgroundTaskManager.d.ts | [startBackgroundRunning(context: Context, bgMode: BackgroundMode, wantAgent: WantAgent, callback: AsyncCallback): void;](../reference/apis/js-apis-resourceschedule-backgroundTaskManager.md#backgroundtaskmanagerstartbackgroundrunningcallback)<br>[startBackgroundRunning(context: Context, bgMode: BackgroundMode, wantAgent: WantAgent): Promise&lt;void&gt;;](../reference/apis/js-apis-resourceschedule-backgroundTaskManager.md#backgroundtaskmanagerstartbackgroundrunningpromise) |
| [cancelBackgroundRunning(callback: AsyncCallback&lt;void&gt;): void;](../reference/apis/js-apis-ability-particleAbility.md#particleabilitycancelbackgroundrunning)<br>[cancelBackgroundRunning(): Promise&lt;void&gt;;](../reference/apis/js-apis-ability-particleAbility.md#particleabilitycancelbackgroundrunning-1) | \@ohos.resourceschedule.backgroundTaskManager.d.ts | [stopBackgroundRunning(context: Context, callback: AsyncCallback): void;](../reference/apis/js-apis-resourceschedule-backgroundTaskManager.md#backgroundtaskmanagerstopbackgroundrunningcallback)<br>[stopBackgroundRunning(context: Context): Promise&lt;void&gt;;](../reference/apis/js-apis-resourceschedule-backgroundTaskManager.md#backgroundtaskmanagerstopbackgroundrunningpromise) | | [cancelBackgroundRunning(callback: AsyncCallback&lt;void&gt;): void;](../reference/apis/js-apis-ability-particleAbility.md#particleabilitycancelbackgroundrunning)<br>[cancelBackgroundRunning(): Promise&lt;void&gt;;](../reference/apis/js-apis-ability-particleAbility.md#particleabilitycancelbackgroundrunning-1) | \@ohos.resourceschedule.backgroundTaskManager.d.ts | [stopBackgroundRunning(context: Context, callback: AsyncCallback): void;](../reference/apis/js-apis-resourceschedule-backgroundTaskManager.md#backgroundtaskmanagerstopbackgroundrunningcallback)<br>[stopBackgroundRunning(context: Context): Promise&lt;void&gt;;](../reference/apis/js-apis-resourceschedule-backgroundTaskManager.md#backgroundtaskmanagerstopbackgroundrunningpromise) |
<!--no_check-->
\ No newline at end of file
...@@ -8,9 +8,9 @@ The OpenHarmony process model is shown below. ...@@ -8,9 +8,9 @@ The OpenHarmony process model is shown below.
- WebView has an independent rendering process, which is **Render process** in yellow in the figure. - WebView has an independent rendering process, which is **Render process** in yellow in the figure.
**Figure 1** Process model **Figure 1** Process model
![process-model-fa](figures/process-model-fa.png) ![process-model-fa](figures/process-model-fa.png)
OpenHarmony provides two inter-process communication (IPC) mechanisms. OpenHarmony provides two inter-process communication (IPC) mechanisms.
...@@ -19,4 +19,3 @@ OpenHarmony provides two inter-process communication (IPC) mechanisms. ...@@ -19,4 +19,3 @@ OpenHarmony provides two inter-process communication (IPC) mechanisms.
- [Common Events](common-event-fa.md): This mechanism is used in one-to-many communication scenarios. Multiple subscribers may receive events at the same time. - [Common Events](common-event-fa.md): This mechanism is used in one-to-many communication scenarios. Multiple subscribers may receive events at the same time.
- [Background Services](rpc.md): This mechanism is implemented through [ServiceAbility](serviceability-overview.md). - [Background Services](rpc.md): This mechanism is implemented through [ServiceAbility](serviceability-overview.md).
...@@ -5,12 +5,11 @@ The OpenHarmony process model is shown below. ...@@ -5,12 +5,11 @@ The OpenHarmony process model is shown below.
- All UIAbility, ServiceExtensionAbility, and DataShareExtensionAbility components of an application (with the same bundle name) run in an independent process, which is **Main process** in green in the figure. - All UIAbility, ServiceExtensionAbility, and DataShareExtensionAbility components of an application (with the same bundle name) run in an independent process, which is **Main process** in green in the figure.
- All ExtensionAbility components of the same type (except ServiceExtensionAbility and DataShareExtensionAbility) of an application (with the same bundle name) run in an independent process, which is **FormExtensionAbility process**, **InputMethodExtensionAbility process**, and other **ExtensionAbility process** in blue in the figure.
- The ExtensionAbility components of the same type (except ServiceExtensionAbility and DataShareExtensionAbility) of an application (with the same bundle name) run in an independent process, which is **FormExtensionAbility process**, **InputMethodExtensionAbility process**, and other **ExtensionAbility process** in blue in the figure.
- WebView has an independent rendering process, which is **Render process** in yellow in the figure. - WebView has an independent rendering process, which is **Render process** in yellow in the figure.
**Figure 1** Process model **Figure 1** Process model
![process-model](figures/process-model.png) ![process-model](figures/process-model.png)
> NOTE > NOTE
...@@ -20,7 +19,8 @@ The OpenHarmony process model is shown below. ...@@ -20,7 +19,8 @@ The OpenHarmony process model is shown below.
A system application can apply for multi-process permissions (as shown in the following figure) and configure a custom process for an HAP. UIAbility, DataShareExtensionAbility, and ServiceExtensionAbility in the HAP run in the custom process. Different HAPs run in different processes by configuring different process names. A system application can apply for multi-process permissions (as shown in the following figure) and configure a custom process for an HAP. UIAbility, DataShareExtensionAbility, and ServiceExtensionAbility in the HAP run in the custom process. Different HAPs run in different processes by configuring different process names.
**Figure 2** Multi-process **Figure 2** Multi-process
![multi-process](figures/multi-process.png) ![multi-process](figures/multi-process.png)
......
# request Switching # request Switching
| API in the FA Model| Corresponding d.ts File in the Stage Model| Corresponding API in the Stage Model| | API in the FA Model| Corresponding .d.ts File in the Stage Model| Corresponding API in the Stage Model|
| -------- | -------- | -------- | | -------- | -------- | -------- |
| [download(config: DownloadConfig, callback: AsyncCallback&lt;DownloadTask&gt;): void;](../reference/apis//js-apis-request.md#requestdownload-1)<br>[download(config: DownloadConfig): Promise&lt;DownloadTask&gt;;](../reference/apis/js-apis-request.md#requestdownload) | \@ohos.request.d.ts | [downloadFile(context: BaseContext, config: DownloadConfig, callback: AsyncCallback&lt;DownloadTask&gt;): void;](../reference/apis/js-apis-request.md#requestdownloadfile9-1)<br>[downloadFile(context: BaseContext, config: DownloadConfig): Promise&lt;DownloadTask&gt;;](../reference/apis/js-apis-request.md#requestdownloadfile9) | | [download(config: DownloadConfig, callback: AsyncCallback&lt;DownloadTask&gt;): void;](../reference/apis//js-apis-request.md#requestdownload-1)<br>[download(config: DownloadConfig): Promise&lt;DownloadTask&gt;;](../reference/apis/js-apis-request.md#requestdownload) | \@ohos.request.d.ts | [downloadFile(context: BaseContext, config: DownloadConfig, callback: AsyncCallback&lt;DownloadTask&gt;): void;](../reference/apis/js-apis-request.md#requestdownloadfile9-1)<br>[downloadFile(context: BaseContext, config: DownloadConfig): Promise&lt;DownloadTask&gt;;](../reference/apis/js-apis-request.md#requestdownloadfile9) |
| [upload(config: UploadConfig, callback: AsyncCallback&lt;UploadTask&gt;): void;](../reference/apis/js-apis-request.md#requestupload-1)<br>[upload(config: UploadConfig): Promise&lt;UploadTask&gt;;](../reference/apis/js-apis-request.md#requestupload) | \@ohos.request.d.ts | [uploadFile(context: BaseContext, config: UploadConfig, callback: AsyncCallback&lt;UploadTask&gt;): void;](../reference/apis/js-apis-request.md#requestuploadfile9-1)<br>[uploadFile(context: BaseContext, config: UploadConfig): Promise&lt;UploadTask&gt;;](../reference/apis/js-apis-request.md#requestuploadfile9) | | [upload(config: UploadConfig, callback: AsyncCallback&lt;UploadTask&gt;): void;](../reference/apis/js-apis-request.md#requestupload-1)<br>[upload(config: UploadConfig): Promise&lt;UploadTask&gt;;](../reference/apis/js-apis-request.md#requestupload) | \@ohos.request.d.ts | [uploadFile(context: BaseContext, config: UploadConfig, callback: AsyncCallback&lt;UploadTask&gt;): void;](../reference/apis/js-apis-request.md#requestuploadfile9-1)<br>[uploadFile(context: BaseContext, config: UploadConfig): Promise&lt;UploadTask&gt;;](../reference/apis/js-apis-request.md#requestuploadfile9) |
# resourceManager Switching # resourceManager Switching
| API in the FA Model| Corresponding d.ts File in the Stage Model| Corresponding Field in the Stage Model| | API in the FA Model| Corresponding .d.ts File in the Stage Model| Corresponding Field in the Stage Model|
| -------- | -------- | -------- | | -------- | -------- | -------- |
| [getResourceManager(callback: AsyncCallback&lt;ResourceManager&gt;): void;](../reference/apis/js-apis-resource-manager.md#resourcemanagergetresourcemanager)<br>[getResourceManager(bundleName: string, callback: AsyncCallback&lt;ResourceManager&gt;): void;](../reference/apis/js-apis-resource-manager.md#resourcemanagergetresourcemanager-1)<br>[getResourceManager(): Promise&lt;ResourceManager&gt;;](../reference/apis/js-apis-resource-manager.md#resourcemanagergetresourcemanager-2)<br>[getResourceManager(bundleName: string): Promise&lt;ResourceManager&gt;;](../reference/apis/js-apis-resource-manager.md#resourcemanagergetresourcemanager-3) | application\Context.d.ts | [resourceManager: resmgr.ResourceManager;](../reference/apis/js-apis-inner-application-context.md#attributes)| | [getResourceManager(callback: AsyncCallback&lt;ResourceManager&gt;): void;](../reference/apis/js-apis-resource-manager.md#resourcemanagergetresourcemanager)<br>[getResourceManager(bundleName: string, callback: AsyncCallback&lt;ResourceManager&gt;): void;](../reference/apis/js-apis-resource-manager.md#resourcemanagergetresourcemanager-1)<br>[getResourceManager(): Promise&lt;ResourceManager&gt;;](../reference/apis/js-apis-resource-manager.md#resourcemanagergetresourcemanager-2)<br>[getResourceManager(bundleName: string): Promise&lt;ResourceManager&gt;;](../reference/apis/js-apis-resource-manager.md#resourcemanagergetresourcemanager-3) | application\Context.d.ts | [resourceManager: resmgr.ResourceManager;](../reference/apis/js-apis-inner-application-context.md#attributes)|
...@@ -4,9 +4,9 @@ ...@@ -4,9 +4,9 @@
The ServiceAbility component in the FA model corresponds to the ServiceExtensionAbility component in the stage model. The ServiceExtensionAbility class provides system APIs. Only system applications can create ServiceExtensionAbility instances. Therefore, ServiceAbility switching adopts different policies for system applications and third-party applications. The ServiceAbility component in the FA model corresponds to the ServiceExtensionAbility component in the stage model. The ServiceExtensionAbility class provides system APIs. Only system applications can create ServiceExtensionAbility instances. Therefore, ServiceAbility switching adopts different policies for system applications and third-party applications.
## Switching a ServiceAbility of a System Application ## Switching a ServiceAbility for a System Application
The procedure for switching a ServiceAbility of a system application is similar to the procedure of PageAbility switching. The procedure for switching a ServiceAbility for a system application is similar to the procedure of PageAbility switching.
1. [Create a ServiceExtensionAbility](serviceextensionability.md) in the stage model. 1. [Create a ServiceExtensionAbility](serviceextensionability.md) in the stage model.
...@@ -24,7 +24,7 @@ The table below describes the lifecycle comparison of the ServiceAbility and Ser ...@@ -24,7 +24,7 @@ The table below describes the lifecycle comparison of the ServiceAbility and Ser
| onStop(): void | onDestroy(): void | The two methods have the same meaning, invoking time, and parameters.| | onStop(): void | onDestroy(): void | The two methods have the same meaning, invoking time, and parameters.|
## Switching a ServiceAbility of a Third-Party Application ## Switching a ServiceAbility for a Third-Party Application
In the stage model, third-party applications cannot provide services for other third-party applications. You can select a switching solution based on your service requirements. In the stage model, third-party applications cannot provide services for other third-party applications. You can select a switching solution based on your service requirements.
......
# Storage Switching # Storage Switching
| API in the FA Model| Corresponding d.ts File in the Stage Model| Corresponding API in the Stage Model| | API in the FA Model| Corresponding .d.ts File in the Stage Model| Corresponding API in the Stage Model|
| -------- | -------- | -------- | | -------- | -------- | -------- |
| GetStorageOptions | There is no corresponding API in the stage model.| The stage model uses **Prefereces** to replace **Storage** and has redesigned the input parameters.| | GetStorageOptions | There is no corresponding API in the stage model.| The stage model uses **Prefereces** to replace **Storage** and has redesigned the input parameters.|
| SetStorageOptions | There is no corresponding API in the stage model.| The stage model uses **Prefereces** to replace **Storage** and has redesigned the input parameters.| | SetStorageOptions | There is no corresponding API in the stage model.| The stage model uses **Prefereces** to replace **Storage** and has redesigned the input parameters.|
......
# Subscribing to System Environment Variable Changes # Subscribing to System Environment Variable Changes
System environment variables are system settings (for example, the system language or screen direction) of a device that may change during the running of an application. System environment variables are system settings (for example, the system language or screen orientation) of a device that may change during the running of an application.
By subscribing to the changes of system environment variables, the application can detect the changes in a timely manner and process the changes accordingly, providing better user experience. For example, when the system language changes, the application can display the UI in the new language; when the user rotates the device to landscape or portrait mode, the application can re-arrange the UI to adapt to the new screen orientation and size. By subscribing to the changes of system environment variables, the application can detect the changes in a timely manner and process the changes accordingly, providing better user experience. For example, when the system language changes, the application can display the UI in the new language; when the user rotates the device to landscape or portrait mode, the application can re-arrange the UI to adapt to the new screen orientation and size.
......
# Thread Model Overview (FA Model) # Thread Model Overview (FA Model)
There are three types of threads in the FA model: There are three types of threads in the FA model:
- Main thread - Main thread
Manages other threads. Manages other threads.
...@@ -14,8 +16,8 @@ There are three types of threads in the FA model: ...@@ -14,8 +16,8 @@ There are three types of threads in the FA model:
- Receives messages sent by the worker thread. - Receives messages sent by the worker thread.
- Worker thread - Worker thread
Performs time-consuming operations Performs time-consuming operations.
Based on the OpenHarmony thread model, different services run on different threads. Service interaction requires inter-thread communication. Threads can communicate with each other in Emitter or Worker mode. Emitter is mainly used for event synchronization between threads, and Worker is mainly used to execute time-consuming tasks. Based on the OpenHarmony thread model, different services run on different threads. Service interaction requires inter-thread communication. Threads can communicate with each other in Emitter or Worker mode. Emitter is mainly used for event synchronization between threads, and Worker is mainly used to execute time-consuming tasks.
......
...@@ -4,19 +4,18 @@ For an OpenHarmony application, each process has a main thread to provide the fo ...@@ -4,19 +4,18 @@ For an OpenHarmony application, each process has a main thread to provide the fo
- Draw the UI. - Draw the UI.
- Manage the ArkTS engine instance of the main thread so that multiple UIAbility components can run on it. - Manage the ArkTS engine instance of the main thread so that multiple UIAbility components can run on it.
- Manage ArkTS engine instances of other threads (such as the worker thread), for example, starting and terminating other threads. - Manage ArkTS engine instances of other threads, for example, starting and terminating other threads.
- Distribute interaction events. - Distribute interaction events.
- Process application code callbacks (event processing and lifecycle management). - Process application code callbacks (event processing and lifecycle management).
- Receive messages sent by the worker thread. - Receive messages sent by the worker thread.
In addition to the main thread, there is an independent thread, named worker. The worker thread is mainly used to perform time-consuming operations. The worker thread is created in the main thread and is independent from the main thread. It cannot directly operate the UI. A maximum of seven worker threads can be created. In addition to the main thread, there is an independent thread, named worker. The worker thread is mainly used to perform time-consuming operations. The worker thread is created in the main thread and is independent from the main thread. It cannot directly operate the UI. A maximum of seven worker threads can be created.
![thread-model-stage](figures/thread-model-stage.png) ![thread-model-stage](figures/thread-model-stage.png)
Based on the OpenHarmony thread model, different services run on different threads. Service interaction requires inter-thread communication. In the same process, threads can communicate with each other in Emitter or Worker mode. Emitter is mainly used for event synchronization between threads, and Worker is mainly used to execute time-consuming tasks. Based on the OpenHarmony thread model, different services run on different threads. Service interaction requires inter-thread communication. In the same process, threads can communicate with each other in Emitter or Worker mode. Emitter is mainly used for event synchronization between threads, and Worker is mainly used to execute time-consuming tasks.
> **NOTE** > **NOTE**
> >
> - The stage model provides only the main thread and worker thread. Emitter is mainly used for event synchronization within the worker thread or between the main thread and worker thread. > - The stage model provides only the main thread and worker thread. Emitter is mainly used for event synchronization within the worker thread or between the main thread and worker thread.
> - The UIAbility and UI are in the main thread. For details about data synchronization between them, see [Data Synchronization Between UIAbility and UI](uiability-data-sync-with-ui.md). > - The UIAbility and UI are in the main thread. For details about data synchronization between them, see [Data Synchronization Between UIAbility and UI](uiability-data-sync-with-ui.md).
> - To view thread information about an application process, run the **hdc shell** command to enter the shell CLI of the device, and then run the **ps -p *<pid>* -T command**, where *<pid>* indicates the [process ID](process-model-stage.md) of the application. > - To view thread information about an application process, run the **hdc shell** command to enter the shell CLI of the device, and then run the **ps -p *<pid>* -T command**, where *<pid>* indicates the [process ID](process-model-stage.md) of the application.
# Data Synchronization Between UIAbility and UI # Data Synchronization Between UIAbility and UI Page
Based on the OpenHarmony application model, you can use any of the following ways to implement data synchronization between the UIAbility component and UI: Based on the OpenHarmony application model, you can use any of the following ways to implement data synchronization between UIAbility components and UI pages:
- [Using EventHub for Data Synchronization](#using-eventhub-for-data-synchronization): The **EventHub** object is provided by the base class **Context**. Events are transferred using the publish/subscribe (pub/sub) pattern. Specifically, after subscribing to an event, your application will receive the event and process it accordingly when the event is published. - [Using EventHub for Data Synchronization](#using-eventhub-for-data-synchronization): The **EventHub** object is provided by the base class **Context**. It allows events to be transferred using the publish/subscribe (pub/sub) pattern. Specifically, after subscribing to an event, your application will receive the event and process it accordingly when the event is published.
- [Using globalThis for Data Synchronization](#using-globalthis-for-data-synchronization): **globalThis** is a global object inside the ArkTS engine instance and can be accessed by components such as UIAbility, ExtensionAbility, and Page. - [Using globalThis for Data Synchronization](#using-globalthis-for-data-synchronization): **globalThis** is a global object inside the ArkTS engine instance and can be accessed by components such as UIAbility, ExtensionAbility, and UI page.
- [Using AppStorage or LocalStorage for Data Synchronization](#using-appstorage-or-localstorage-for-data-synchronization): ArkUI provides two application-level state management solutions: AppStorage and LocalStorage, which implement application- and UIAbility-level data synchronization, respectively. - [Using AppStorage or LocalStorage for Data Synchronization](#using-appstorage-or-localstorage-for-data-synchronization): ArkUI provides two application-level state management solutions: AppStorage and LocalStorage, which implement application- and UIAbility-level data synchronization, respectively.
...@@ -12,7 +12,7 @@ Based on the OpenHarmony application model, you can use any of the following way ...@@ -12,7 +12,7 @@ Based on the OpenHarmony application model, you can use any of the following way
[EventHub](../reference/apis/js-apis-inner-application-eventHub.md) provides an event mechanism for the UIAbility or ExtensionAbility component so that they can subscribe to, unsubscribe from, and trigger events. [EventHub](../reference/apis/js-apis-inner-application-eventHub.md) provides an event mechanism for the UIAbility or ExtensionAbility component so that they can subscribe to, unsubscribe from, and trigger events.
Before using the APIs provided by **EventHub**, you must obtain an **EventHub** object, which is provided by the [base class Context](application-context-stage.md). This section uses EventHub as an example to describe how to implement data synchronization between the UIAbility component and the UI. Before using the APIs provided by **EventHub**, you must obtain an **EventHub** object, which is provided by the [base class Context](application-context-stage.md).
1. Call [eventHub.on()](../reference/apis/js-apis-inner-application-eventHub.md#eventhubon) in the UIAbility in either of the following ways to register a custom event **event1**. 1. Call [eventHub.on()](../reference/apis/js-apis-inner-application-eventHub.md#eventhubon) in the UIAbility in either of the following ways to register a custom event **event1**.
...@@ -40,7 +40,7 @@ Before using the APIs provided by **EventHub**, you must obtain an **EventHub** ...@@ -40,7 +40,7 @@ Before using the APIs provided by **EventHub**, you must obtain an **EventHub**
} }
``` ```
2. Call [eventHub.emit()](../reference/apis/js-apis-inner-application-eventHub.md#eventhubemit) on the UI to trigger the event, and pass the parameters as required. 2. Call [eventHub.emit()](../reference/apis/js-apis-inner-application-eventHub.md#eventhubemit) on the UI page to trigger the event, and pass in the parameters as required.
```ts ```ts
import common from '@ohos.app.ability.common'; import common from '@ohos.app.ability.common';
...@@ -60,14 +60,14 @@ Before using the APIs provided by **EventHub**, you must obtain an **EventHub** ...@@ -60,14 +60,14 @@ Before using the APIs provided by **EventHub**, you must obtain an **EventHub**
// You can design the parameters based on your service requirements. // You can design the parameters based on your service requirements.
} }
// Page display. // UI page display.
build() { build() {
... ...
} }
} }
``` ```
3. Obtain the event trigger result from the subscription callback of UIAbility. The run log result is as follows: 3. Obtain the event trigger result from the subscription callback of the UIAbility. The run log result is as follows:
```ts ```ts
[] []
...@@ -77,7 +77,7 @@ Before using the APIs provided by **EventHub**, you must obtain an **EventHub** ...@@ -77,7 +77,7 @@ Before using the APIs provided by **EventHub**, you must obtain an **EventHub**
[2,'test'] [2,'test']
``` ```
4. After **event1** is used, you can call [eventHub.off()](../reference/apis/js-apis-inner-application-eventHub.md#eventhuboff) to unsubscribe from the event. 4. When **event1** is not needed, call [eventHub.off()](../reference/apis/js-apis-inner-application-eventHub.md#eventhuboff) to unsubscribe from the event.
```ts ```ts
// context is the AbilityContext of the UIAbility instance. // context is the AbilityContext of the UIAbility instance.
...@@ -87,7 +87,7 @@ Before using the APIs provided by **EventHub**, you must obtain an **EventHub** ...@@ -87,7 +87,7 @@ Before using the APIs provided by **EventHub**, you must obtain an **EventHub**
## Using globalThis for Data Synchronization ## Using globalThis for Data Synchronization
**globalThis** is a global object inside the [ArkTS engine instance](thread-model-stage.md) and can be used by UIAbility, ExtensionAbility, and Page inside the engine. Therefore, you can use **globalThis** for data synchronization. **globalThis** is a global object inside the [ArkTS engine instance](thread-model-stage.md) and can be used by UIAbility, ExtensionAbility, and UI page inside the engine. Therefore, you can use **globalThis** for data synchronization.
**Figure 1** Using globalThis for data synchronization **Figure 1** Using globalThis for data synchronization
![globalThis1](figures/globalThis1.png) ![globalThis1](figures/globalThis1.png)
...@@ -95,16 +95,16 @@ Before using the APIs provided by **EventHub**, you must obtain an **EventHub** ...@@ -95,16 +95,16 @@ Before using the APIs provided by **EventHub**, you must obtain an **EventHub**
The following describes how to use **globalThis** in three scenarios. Precautions are provided as well. The following describes how to use **globalThis** in three scenarios. Precautions are provided as well.
- [Using globalThis Between UIAbility and Page](#using-globalthis-between-uiability-and-page) - [Using globalThis Between UIAbility and UI Page](#using-globalthis-between-uiability-and-ui-page)
- [Using globalThis Between UIAbility and UIAbility](#using-globalthis-between-uiability-and-uiability) - [Using globalThis Between UIAbility and UIAbility](#using-globalthis-between-uiability-and-uiability)
- [Use globalThis Between UIAbility and ExtensionAbility](#using-globalthis-between-uiability-and-extensionability) - [Using globalThis Between UIAbility and ExtensionAbility](#using-globalthis-between-uiability-and-extensionability)
- [Precautions for Using globalThis](#precautions-for-using-globalthis) - [Precautions for Using globalThis](#precautions-for-using-globalthis)
### Using globalThis Between UIAbility and Page ### Using globalThis Between UIAbility and UI Page
By binding attributes or methods to **globalThis**, you can implement data synchronization between the UIAbility component and UI. For example, if you bind the **want** parameter in the UIAbility component, you can use the **want** parameter information on the UI corresponding to the UIAbility component. To implement data synchronization between the UIAbility component and UI page, you can bind attributes or methods to **globalThis**. For example, if you bind the **want** parameter in the UIAbility component, you can use the **want** parameter information on the UI page corresponding to the UIAbility component.
1. When [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) is called to start a UIAbility instance, the [onCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate) callback is invoked, and the **want** parameter can be passed in the callback. Therefore, you can bind the **want** parameter to **globalThis**. 1. When [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) is called to start a UIAbility instance, the [onCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate) callback is invoked, and the **want** parameter can be passed in the callback. Bind the **want** parameter to **globalThis**.
```ts ```ts
import UIAbility from '@ohos.app.ability.UIAbility'; import UIAbility from '@ohos.app.ability.UIAbility';
...@@ -119,7 +119,7 @@ By binding attributes or methods to **globalThis**, you can implement data synch ...@@ -119,7 +119,7 @@ By binding attributes or methods to **globalThis**, you can implement data synch
} }
``` ```
2. Use **globalThis** on the UI to obtain the **want** parameter information. 2. Use **globalThis** on the UI page to obtain the **want** parameter information.
```ts ```ts
let entryAbilityWant; let entryAbilityWant;
...@@ -131,7 +131,7 @@ By binding attributes or methods to **globalThis**, you can implement data synch ...@@ -131,7 +131,7 @@ By binding attributes or methods to **globalThis**, you can implement data synch
entryAbilityWant = globalThis.entryAbilityWant; entryAbilityWant = globalThis.entryAbilityWant;
} }
// Page display. // UI page display.
build() { build() {
... ...
} }
...@@ -143,7 +143,7 @@ By binding attributes or methods to **globalThis**, you can implement data synch ...@@ -143,7 +143,7 @@ By binding attributes or methods to **globalThis**, you can implement data synch
To implement data synchronization between two UIAbility components in the same application, you can bind data to **globalThis**. For example, you can save data in **globalThis** in UIAbilityA and obtain the data from UIAbilityB. To implement data synchronization between two UIAbility components in the same application, you can bind data to **globalThis**. For example, you can save data in **globalThis** in UIAbilityA and obtain the data from UIAbilityB.
1. UIAbilityA stores a string and binds it to globalThis. 1. Save data in UIAbilityA and bind it to **globalThis**.
```ts ```ts
import UIAbility from '@ohos.app.ability.UIAbility' import UIAbility from '@ohos.app.ability.UIAbility'
...@@ -175,7 +175,7 @@ To implement data synchronization between two UIAbility components in the same a ...@@ -175,7 +175,7 @@ To implement data synchronization between two UIAbility components in the same a
To implement data synchronization between the UIAbility and ExtensionAbility components in the same application, you can bind data to **globalThis**. For example, you can save data in **globalThis** in UIAbilityA and obtain the data from ServiceExtensionAbility. To implement data synchronization between the UIAbility and ExtensionAbility components in the same application, you can bind data to **globalThis**. For example, you can save data in **globalThis** in UIAbilityA and obtain the data from ServiceExtensionAbility.
1. UIAbilityA stores a string and binds it to globalThis. 1. Save data in UIAbilityA and bind it to **globalThis**.
```ts ```ts
import UIAbility from '@ohos.app.ability.UIAbility' import UIAbility from '@ohos.app.ability.UIAbility'
...@@ -206,18 +206,18 @@ To implement data synchronization between the UIAbility and ExtensionAbility com ...@@ -206,18 +206,18 @@ To implement data synchronization between the UIAbility and ExtensionAbility com
### Precautions for Using globalThis ### Precautions for Using globalThis
**Figure 2** Precautions for globalThis **Figure 2** Precautions for using globalThis
![globalThis2](figures/globalThis2.png) ![globalThis2](figures/globalThis2.png)
- In the stage model, all the UIAbility components in a process share one ArkTS engine instance. When using **globalThis**, do not store objects with the same name. For example, if UIAbilityA and UIAbilityB use **globalThis** to store two objects with the same name, the object stored earlier will be overwritten. - In the stage model, all the UIAbility components in a process share one ArkTS engine instance. When using **globalThis**, do not store objects with the same name. For example, if UIAbilityA and UIAbilityB use **globalThis** to store two objects with the same name, the object stored earlier will be overwritten.
- This problem does not occur in the FA model because each UIAbility component uses an independent engine. - This problem does not occur in the FA model because each UIAbility component uses an independent engine.
- The lifecycle of an object bound to **globalThis** is the same as that of the ArkTS engine instance. You are advised to assign the value **null** after using the object to minimize memory usage. - The lifecycle of an object bound to **globalThis** is the same as that of the ArkTS engine instance. To minimize memory usage, you are advised to assign the value **null** to the object when it is not in use.
The following provides an example to describe the object overwritten problem in the stage model. The following provides an example to describe the object overwritten problem in the stage model.
1. In the UIAbilityA file, [UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md) is stored in **globalThis**. 1. In the UIAbilityA file, use **globalThis** to store [UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md).
```ts ```ts
import UIAbility from '@ohos.app.ability.UIAbility' import UIAbility from '@ohos.app.ability.UIAbility'
...@@ -230,7 +230,7 @@ The following provides an example to describe the object overwritten problem in ...@@ -230,7 +230,7 @@ The following provides an example to describe the object overwritten problem in
} }
``` ```
2. Obtain and use [UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md) on the page of UIAbilityA. After the UIAbilityA instance is used, switch it to the background. 2. Obtain and use [UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md) on the UI page of UIAbilityA. When the UIAbilityA instance is not in use, switch it to the background.
```ts ```ts
@Entry @Entry
...@@ -239,14 +239,14 @@ The following provides an example to describe the object overwritten problem in ...@@ -239,14 +239,14 @@ The following provides an example to describe the object overwritten problem in
onPageShow() { onPageShow() {
let ctx = globalThis.context; // Obtain the context from globalThis and use it. let ctx = globalThis.context; // Obtain the context from globalThis and use it.
} }
// Page display. // UI page display.
build() { build() {
... ...
} }
} }
``` ```
3. In the UIAbilityB file, [UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md) is stored in **globalThis** and has the same name as that in the UIAbilityA file. 3. In the UIAbilityB file, use **globalThis** to store [UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md), which is named the same as that in the UIAbilityA file.
```ts ```ts
import UIAbility from '@ohos.app.ability.UIAbility' import UIAbility from '@ohos.app.ability.UIAbility'
...@@ -260,7 +260,7 @@ The following provides an example to describe the object overwritten problem in ...@@ -260,7 +260,7 @@ The following provides an example to describe the object overwritten problem in
} }
``` ```
4. Obtain and use [UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md) on the page of UIAbilityB. The obtained **globalThis.context** is the value of [UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md) in UIAbilityB. 4. Obtain [UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md) from the UI page of UIAbilityB and use it. The obtained **globalThis.context** is the value of [UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md) in UIAbilityB.
```ts ```ts
@Entry @Entry
...@@ -269,7 +269,7 @@ The following provides an example to describe the object overwritten problem in ...@@ -269,7 +269,7 @@ The following provides an example to describe the object overwritten problem in
onPageShow() { onPageShow() {
let ctx = globalThis.context; // Obtain the context from globalThis and use it. let ctx = globalThis.context; // Obtain the context from globalThis and use it.
} }
// Page display. // UI page display.
build() { build() {
... ...
} }
...@@ -289,7 +289,7 @@ The following provides an example to describe the object overwritten problem in ...@@ -289,7 +289,7 @@ The following provides an example to describe the object overwritten problem in
} }
``` ```
6. When the page of UIAbilityA is displayed, the obtained **globalThis.context** is [UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md) of UIAbilityB instead of UIAbilityA. An error occurs. 6. When the UI page of UIAbilityA is displayed, the obtained **globalThis.context** is the value of [UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md) of UIAbilityB instead of UIAbilityA. An error occurs.
```ts ```ts
@Entry @Entry
...@@ -298,7 +298,7 @@ The following provides an example to describe the object overwritten problem in ...@@ -298,7 +298,7 @@ The following provides an example to describe the object overwritten problem in
onPageShow() { onPageShow() {
let ctx = globalThis.context; // The context in globalThis is the context of UIAbilityB. let ctx = globalThis.context; // The context in globalThis is the context of UIAbilityB.
} }
// Page display. // UI page display.
build() { build() {
... ...
} }
...@@ -307,4 +307,4 @@ The following provides an example to describe the object overwritten problem in ...@@ -307,4 +307,4 @@ The following provides an example to describe the object overwritten problem in
## Using AppStorage or LocalStorage for Data Synchronization ## Using AppStorage or LocalStorage for Data Synchronization
ArkUI provides AppStorage and LocalStorage to implement application- and UIAbility-level data synchronization, respectively. Both solutions can be used to manage the application state, enhance application performance, and improve user experience. The AppStorage is a global state manager and is applicable when multiple UIAbilities share the same state data. The LocalStorage is a local state manager that manages state data used inside a single UIAbility. They help you control the application state more flexibly and improve the maintainability and scalability of applications. For details, see [State Management of Application-Level Variables](../quick-start/arkts-application-state-management-overview.md). ArkUI provides AppStorage and LocalStorage to implement application- and UIAbility-level data synchronization, respectively. Both solutions can be used to manage the application state, enhance application performance, and improve user experience. The AppStorage is a global state manager that manages state data shared among multiple UIAbilities. The LocalStorage is a local state manager that manages state data used inside a single UIAbility. They help you control the application state more flexibly and improve the maintainability and scalability of applications. For details, see [State Management of Application-Level Variables](../quick-start/arkts-application-state-management-overview.md).
# UIAbility Component Launch Type # UIAbility Launch Type
The launch type of the UIAbility component refers to the state of the UIAbility instance at startup. The system provides three launch types: The launch type of the UIAbility component refers to the state of the UIAbility instance at startup. Three launch types are available:
- [Singleton](#singleton) - [Singleton](#singleton)
...@@ -15,7 +15,7 @@ The launch type of the UIAbility component refers to the state of the UIAbility ...@@ -15,7 +15,7 @@ The launch type of the UIAbility component refers to the state of the UIAbility
**singleton** is the default launch type. **singleton** is the default launch type.
Each time [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) is called, if a UIAbility instance of this type already exists in the application process, the instance is reused. Therefore, only one UIAbility instance of this type exists in the system, that is, displayed in **Recents**. Each time [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) is called, if a UIAbility instance of this type already exists in the application process, the instance is reused. In other words, UIAbility of this type can have only one instance in the system, meaning that only one mission is displayed in the system application Recents.
**Figure 1** Demonstration effect in singleton mode **Figure 1** Demonstration effect in singleton mode
...@@ -23,9 +23,9 @@ Each time [startAbility()](../reference/apis/js-apis-inner-application-uiAbility ...@@ -23,9 +23,9 @@ Each time [startAbility()](../reference/apis/js-apis-inner-application-uiAbility
> **NOTE** > **NOTE**
> >
> Assume that the application already has a UIAbility instance created, and the launch type of the UIAbility instance is set to **singleton**. If [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) is called again to start the UIAbility instance, the original UIAbility instance is started, and no new UIAbility instance is created. In this case, the [onNewWant()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant) callback is invoked, but the [onCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate) and [onWindowStageCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityonwindowstagecreate) callbacks are not. > If [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) is called to start an existing UIAbility instance in singleton mode, that instance is started, and no new UIAbility instance is created. In this case, the [onNewWant()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant) callback is invoked, but the [onCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate) and [onWindowStageCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityonwindowstagecreate) callbacks are not.
To use the singleton mode, set **launchType** in the [module.json5 configuration file](../quick-start/module-configuration-file.md) to **singleton**. To use the singleton mode, set **launchType** in the [module.json5 file](../quick-start/module-configuration-file.md) to **singleton**.
```json ```json
...@@ -45,7 +45,7 @@ To use the singleton mode, set **launchType** in the [module.json5 configuration ...@@ -45,7 +45,7 @@ To use the singleton mode, set **launchType** in the [module.json5 configuration
## Multiton ## Multiton
In multiton mode, each time [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) is called, a new UIAbility instance of this type is created in the application process. Multiple UIAbility instances of this type are displayed in **Recents**. In multiton mode, each time [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) is called, a new UIAbility instance is created in the application process. Multiple missions are displayed for UIAbility of this type in Recents.
**Figure 2** Demonstration effect in multiton mode **Figure 2** Demonstration effect in multiton mode
...@@ -71,15 +71,15 @@ To use the multiton mode, set **launchType** in the [module.json5 file](../quick ...@@ -71,15 +71,15 @@ To use the multiton mode, set **launchType** in the [module.json5 file](../quick
## Specified ## Specified
The **specified** mode is used in some special scenarios. For example, in a document application, you want a document instance to be created each time you create a document, but you want to use the same document instance when you repeatedly open an existing document. The **specified** mode is used in some special scenarios. For example, in a document application, you may want a document instance to be created each time you create a document, and you may also want to use the same document instance when you open an existing document.
**Figure 3** Demonstration effect in specified mode **Figure 3** Demonstration effect in specified mode
![uiability-launch-type3](figures/uiability-launch-type3.gif) ![uiability-launch-type3](figures/uiability-launch-type3.gif)
For example, there are two UIAbility components: EntryAbility and SpecifiedAbility (with the launch type **specified**). You are required to start SpecifiedAbility from EntryAbility. In the following example, there are two UIAbility components: EntryAbility and SpecifiedAbility (with the launch type **specified**). To start SpecifiedAbility from EntryAbility, proceed as follows:
1. In SpecifiedAbility, set the **launchType** field in the [module.json5 file](../quick-start/module-configuration-file.md) to **specified**. 1. In SpecifiedAbility, set **launchType** in the [module.json5 file](../quick-start/module-configuration-file.md) to **specified**.
```json ```json
{ {
...@@ -95,10 +95,10 @@ For example, there are two UIAbility components: EntryAbility and SpecifiedAbili ...@@ -95,10 +95,10 @@ For example, there are two UIAbility components: EntryAbility and SpecifiedAbili
} }
``` ```
2. Create a unique string key for the instance. Each time [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) is called, the application, based on the key, identifies the UIAbility instance used to respond to the request. In EntryAbility, add a custom parameter, for example, **instanceKey**, to the **want** parameter in [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) to distinguish the UIAbility instance. 2. Create a unique string key for the SpecifiedAbility instance. Each time [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) is called, the application, based on the key, identifies the UIAbility instance used to respond to the request. In EntryAbility, add a custom parameter, for example, **instanceKey**, to the **want** parameter in [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) to distinguish the UIAbility instances.
```ts ```ts
// Configure an independent key for each UIAbility instance. // Configure a unique key for each UIAbility instance.
// For example, in the document usage scenario, use the document path as the key. // For example, in the document usage scenario, use the document path as the key.
function getInstance() { function getInstance() {
... ...
...@@ -122,16 +122,16 @@ For example, there are two UIAbility components: EntryAbility and SpecifiedAbili ...@@ -122,16 +122,16 @@ For example, there are two UIAbility components: EntryAbility and SpecifiedAbili
}) })
``` ```
3. Before SpecifiedAbility is started, the [onAcceptWant()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant) callback of the corresponding AbilityStage instance is invoked to obtain the key of the UIAbility, because the launch type of SpecifiedAbility is set to **specified**. If a UIAbility instance matching the key exists, the system starts the UIAbility instance and invokes its [onNewWant()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant) callback. Otherwise, the system creates a new UIAbility instance and invokes its [onCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate) and [onWindowStageCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityonwindowstagecreate) callbacks. 3. Before SpecifiedAbility is started, the [onAcceptWant()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant) callback of the corresponding AbilityStage instance is invoked to obtain the key of the target UIAbility. If a UIAbility instance matching the key exists, the system starts the UIAbility instance and invokes its [onNewWant()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant) callback. Otherwise, the system creates a new UIAbility instance and invokes its [onCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate) and [onWindowStageCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityonwindowstagecreate) callbacks.
In the sample code, the [onAcceptWant()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant) callback parses the **want** parameter to obtain the custom parameter **instanceKey**. The service logic returns a key string based on **instanceKey** parameter to identify the UIAbility instance. If the returned key maps to a started UIAbility instance, the system pulls the UIAbility instance back to the foreground and obtains the focus. If the returned key does not map to a started UIAbility instance, the system creates a new UIAbility instance and starts it. In the sample code, the [onAcceptWant()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant) callback uses the passed **want** parameter to obtain the custom parameter **instanceKey**. The service logic returns a key string based on the **instanceKey** parameter to identify the UIAbility instance. If the returned key maps to a started UIAbility instance, the system pulls the UIAbility instance back to the foreground and gives it the focus. If the returned key does not map to a started UIAbility instance, the system creates a new UIAbility instance and starts it.
```ts ```ts
import AbilityStage from '@ohos.app.ability.AbilityStage'; import AbilityStage from '@ohos.app.ability.AbilityStage';
export default class MyAbilityStage extends AbilityStage { export default class MyAbilityStage extends AbilityStage {
onAcceptWant(want): string { onAcceptWant(want): string {
// In the AbilityStage instance of the callee, a key value corresponding to a UIAbility instance is returned for UIAbility whose launch type is specified. // In the AbilityStage instance of the callee, a key string corresponding to a UIAbility instance is returned for UIAbility whose launch type is specified.
// In this example, SpecifiedAbility of module1 is returned. // In this example, SpecifiedAbility of module1 is returned.
if (want.abilityName === 'SpecifiedAbility') { if (want.abilityName === 'SpecifiedAbility') {
// The returned key string is a custom string. // The returned key string is a custom string.
...@@ -145,15 +145,16 @@ For example, there are two UIAbility components: EntryAbility and SpecifiedAbili ...@@ -145,15 +145,16 @@ For example, there are two UIAbility components: EntryAbility and SpecifiedAbili
> **NOTE** > **NOTE**
> >
> 1. Assume that the application already has a UIAbility instance created, and the launch type of the UIAbility instance is set to **specified**. If [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) is called again to start the UIAbility instance, and the [onAcceptWant()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant) callback of [AbilityStage](../reference/apis/js-apis-app-ability-abilityStage.md) matches a created UIAbility instance, the original UIAbility instance is started, and no new UIAbility instance is created. In this case, the [onNewWant()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant) callback is invoked, but the [onCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate) and [onWindowStageCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityonwindowstagecreate) callbacks are not. > - If [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) is called to start an existing UIAbility instance in specified mode, and the [onAcceptWant()](../reference/apis/js-apis-app-ability-abilityStage.md#abilitystageonacceptwant) callback of [AbilityStage](../reference/apis/js-apis-app-ability-abilityStage.md) matches that UIAbility instance, that instance is started, and no new UIAbility instance is created. In this case, the [onNewWant()](../reference/apis/js-apis-app-ability-uiAbility.md#abilityonnewwant) callback is invoked, but the [onCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate) and [onWindowStageCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityonwindowstagecreate) callbacks are not.
> 2. AbilityStage is not automatically generated in the default project of DevEco Studio. For details about how to create an AbilityStage file, see [AbilityStage Component Container](abilitystage.md). >
> - AbilityStage is not automatically generated by default in the project of DevEco Studio. For details about how to create an AbilityStage file, see [AbilityStage Component Container](abilitystage.md).
For example, in the document application, different keys are bound to different document instances. Each time a document is created, a new key (for example, file path) is passed, and a new UIAbility instance is created when UIAbility is started in AbilityStage. However, when you open an existing document, the same UIAbility instance is started again in AbilityStage.
The following steps are used as an example. For example, in the document application, different keys are bound to different document instances. Each time a document is created, a new key (for example, file path) is passed in, and a new UIAbility instance is created when UIAbility is started in AbilityStage. However, when an existing document is opened, the same UIAbility instance is started again in AbilityStage.
1. Open file A. A UIAbility instance, for example, UIAbility instance 1, is started. The following steps are used as an example.
2. Close the process of file A in **Recents**. UIAbility instance 1 is destroyed. Return to the home screen and open file A again. A new UIAbility instance is started, for example, UIAbility instance 2.
3. Return to the home screen and open file B. A new UIAbility instance is started, for example, UIAbility instance 3.
4. Return to the home screen and open file A again. UIAbility instance 2 is started. This is because the system automatically matches the key of the UIAbility instance and starts the UIAbility instance that has a matching key. In this example, UIAbility instance 2 has the same key as file A. Therefore, the system pulls back UIAbility instance 2 and focuses it without creating a new instance.
1. Open file A. A UIAbility instance, UIAbility instance 1, is started.
2. Close the process of file A in Recents. UIAbility instance 1 is destroyed. Return to the home screen and open file A again. A new UIAbility instance, UIAbility instance 2, is started.
3. Return to the home screen and open file B. A new UIAbility instance, UIAbility instance 3, is started.
4. Return to the home screen and open file A again. UIAbility instance 2 is started. This is because the system automatically matches the key with the UIAbility instance and starts the UIAbility instance that has a matching key. In this example, UIAbility instance 2 has the same key as file A. Therefore, the system pulls back UIAbility instance 2 and focuses it without creating a new instance.hao
# UIAbility Component Lifecycle # UIAbility Lifecycle
## Overview ## Overview
When a user opens, switches, and returns to an application, the UIAbility instances in the application transit in their different states. The UIAbility class provides a series of callbacks. Through these callbacks, you can know the state changes of the UIAbility instance, for example, being created or destroyed, or running in the foreground or background. When a user opens or switches to and from an application, the UIAbility instances in the application transit in their different states. The UIAbility class provides a series of callbacks. Through these callbacks, you can know the state changes of the UIAbility instance.
The lifecycle of UIAbility has four states: **Create**, **Foreground**, **Background**, and **Destroy**, as shown in the figure below. The lifecycle of UIAbility has four states: **Create**, **Foreground**, **Background**, and **Destroy**, as shown in the figure below.
...@@ -17,7 +17,7 @@ The lifecycle of UIAbility has four states: **Create**, **Foreground**, **Backgr ...@@ -17,7 +17,7 @@ The lifecycle of UIAbility has four states: **Create**, **Foreground**, **Backgr
### Create ### Create
The **Create** state is triggered when the UIAbility instance is created during application loading. The system invokes the **onCreate()** callback. In this callback, you can perform application initialization operations, for example, defining variables or loading resources. The **Create** state is triggered when the UIAbility instance is created during application loading. It corresponds to the **onCreate()** callback. In this callback, you can perform application initialization operations, for example, defining variables or loading resources.
```ts ```ts
...@@ -33,13 +33,14 @@ export default class EntryAbility extends UIAbility { ...@@ -33,13 +33,14 @@ export default class EntryAbility extends UIAbility {
> **NOTE** > **NOTE**
> >
> [Want](../reference/apis/js-apis-app-ability-want.md) is used as the carrier to transfer information between application components. For details, see [Want](want-overview.md). > The [want](../reference/apis/js-apis-app-ability-want.md) parameter in the **onCreate()** callback is used as the carrier to transfer information between application components. For details, see [Want](want-overview.md).
### WindowStageCreate and WindowStageDestory ### WindowStageCreate and WindowStageDestory
After the UIAbility instance is created but before it enters the **Foreground** state, the system creates a WindowStage instance and triggers the **onWindowStageCreate()** callback. You can set UI loading and WindowStage event subscription in the callback. After the UIAbility instance is created but before it enters the **Foreground** state, the system creates a WindowStage instance and triggers the **onWindowStageCreate()** callback. You can set UI loading and WindowStage event subscription in the callback.
**Figure 2** WindowStageCreate and WindowStageDestory **Figure 2** WindowStageCreate and WindowStageDestory
![Ability-Life-Cycle-WindowStage](figures/Ability-Life-Cycle-WindowStage.png) ![Ability-Life-Cycle-WindowStage](figures/Ability-Life-Cycle-WindowStage.png)
In the **onWindowStageCreate()** callback, use [loadContent()](../reference/apis/js-apis-window.md#loadcontent9-2) to set the page to be loaded, and call [on('windowStageEvent')](../reference/apis/js-apis-window.md#onwindowstageevent9) to subscribe to [WindowStage events](../reference/apis/js-apis-window.md#windowstageeventtype9), for example, having or losing focus, or becoming visible or invisible. In the **onWindowStageCreate()** callback, use [loadContent()](../reference/apis/js-apis-window.md#loadcontent9-2) to set the page to be loaded, and call [on('windowStageEvent')](../reference/apis/js-apis-window.md#onwindowstageevent9) to subscribe to [WindowStage events](../reference/apis/js-apis-window.md#windowstageeventtype9), for example, having or losing focus, or becoming visible or invisible.
...@@ -78,7 +79,7 @@ export default class EntryAbility extends UIAbility { ...@@ -78,7 +79,7 @@ export default class EntryAbility extends UIAbility {
JSON.stringify(exception)); JSON.stringify(exception));
} }
// Set UI loading. // Set the page to be loaded.
windowStage.loadContent('pages/Index', (err, data) => { windowStage.loadContent('pages/Index', (err, data) => {
... ...
}); });
...@@ -86,7 +87,7 @@ export default class EntryAbility extends UIAbility { ...@@ -86,7 +87,7 @@ export default class EntryAbility extends UIAbility {
} }
``` ```
> **NOTE**<br> > **NOTE**
> >
> For details about how to use WindowStage, see [Window Development](../windowmanager/application-window-stage.md). > For details about how to use WindowStage, see [Window Development](../windowmanager/application-window-stage.md).
...@@ -121,15 +122,15 @@ export default class EntryAbility extends UIAbility { ...@@ -121,15 +122,15 @@ export default class EntryAbility extends UIAbility {
### Foreground and Background ### Foreground and Background
The **Foreground** and **Background** states are triggered when the UIAbility instance is switched to the foreground and background respectively. They correspond to the **onForeground()** and **onBackground()** callbacks. The **Foreground** and **Background** states are triggered when the UIAbility instance is switched to the foreground and background, respectively. They correspond to the **onForeground()** and **onBackground()** callbacks.
The **onForeground()** callback is triggered before the UI of the UIAbility instance becomes visible, for example, when the UIAbility instance is switched to the foreground. In this callback, you can apply for resources required by the system or re-apply for resources that have been released in the **onBackground()** callback. The **onForeground()** callback is triggered when the UI of the UIAbility instance is about to become visible, for example, when the UIAbility instance is about to enter the foreground. In this callback, you can apply for resources required by the system or re-apply for resources that have been released in the **onBackground()** callback.
The **onBackground()** callback is triggered after the UI of the UIAbility component is completely invisible, for example, when the UIAbility instance is switched to the background. In this callback, you can release useless resources or perform time-consuming operations such as saving the status. The **onBackground()** callback is triggered when the UI of the UIAbility instance is about to become invisible, for example, when the UIAbility instance is about to enter the background. In this callback, you can release unused resources or perform time-consuming operations such as saving the status.
For example, an application needs to use positioning, and the application has requested the positioning permission from the user. Before the UI is displayed, you can enable positioning in the **onForeground()** callback to obtain the location information. For example, there is an application that requires location access and has obtained the location permission from the user. Before the UI is displayed, you can enable location in the **onForeground()** callback to obtain the location information.
When the application is switched to the background, you can disable positioning in the **onBackground()** callback to reduce system resource consumption. When the application is switched to the background, you can disable location in the **onBackground()** callback to reduce system resource consumption.
```ts ```ts
...@@ -143,7 +144,7 @@ export default class EntryAbility extends UIAbility { ...@@ -143,7 +144,7 @@ export default class EntryAbility extends UIAbility {
} }
onBackground() { onBackground() {
// Release useless resources when the UI is invisible, or perform time-consuming operations in this callback, // Release unused resources when the UI is invisible, or perform time-consuming operations in this callback,
// for example, saving the status. // for example, saving the status.
} }
} }
...@@ -154,7 +155,7 @@ export default class EntryAbility extends UIAbility { ...@@ -154,7 +155,7 @@ export default class EntryAbility extends UIAbility {
The **Destroy** state is triggered when the UIAbility instance is destroyed. You can perform operations such as releasing system resources and saving data in the **onDestroy()** callback. The **Destroy** state is triggered when the UIAbility instance is destroyed. You can perform operations such as releasing system resources and saving data in the **onDestroy()** callback.
The UIAbility instance is destroyed when **terminateSelf()** is called or the user closes the instance in **Recents**. The UIAbility instance is destroyed when **terminateSelf()** is called or the user closes the instance in the system application Recents.
```ts ```ts
import UIAbility from '@ohos.app.ability.UIAbility'; import UIAbility from '@ohos.app.ability.UIAbility';
......
# UIAbility Component Overview # UIAbility Overview
## Overview ## Overview
UIAbility is a type of application component that provides the UI for user interaction. UIAbility is a type of application component that provides the UI for user interactions.
The following design philosophy is behind UIAbility: The following design philosophy is behind UIAbility:
1. Native support for [cross-device migration](hop-cross-device-migration.md) and [multi-device collaboration](hop-multi-device-collaboration.md) at the application component level 1. Native support for [cross-device migration](hop-cross-device-migration.md) and [multi-device collaboration](hop-multi-device-collaboration.md) at the application component level
2. Support for multiple device types and window forms 2. Support for multiple device types and window modes
> **NOTE** > **NOTE**
> >
> For details, see [Interpretation of the Application Model](application-model-description.md). > For details, see [Interpretation of the Application Model](application-model-description.md).
The UIAbility division principles and suggestions are as follows: UIAbility is the basic unit of scheduling in OpenHarmony and provides a window for applications to draw the UI. An application can contain one or more UIAbility components. For example, for a payment application, you can use separate UIAbility components to carry the entry and payment functionalities.
UIAbility is the basic unit scheduled by the system and provides a window for applications to draw UIs. An application can contain one or more UIAbility components. For example, for a payment application, you can use two UIAbility components to carry the entry and payment functionalities. Each UIAbility component instance is displayed as a mission in the system application Recents.
Each UIAbility component instance is displayed as a mission in Recents.
You can develop a single UIAbility or multiple UIAbilities for your application based on service requirements. You can develop a single UIAbility or multiple UIAbilities for your application based on service requirements.
- If you want only one mission to be displayed in Recents, use one UIAbility and multiple pages. - If you want your application to be displayed as one mission in Recents, use one UIAbility and multiple pages.
- If you want multiple missions to be displayed in Recents or multiple windows to be opened simultaneously, use multiple UIAbilities. - If you want your application to be displayed as multiple missions in Recents or multiple windows to be opened simultaneously, use multiple UIAbilities.
## Privacy Statement Configuration ## Declaration Configuration
To enable an application to properly use a UIAbility component, declare the UIAbility name, entry, and tags under [abilities](../quick-start/module-configuration-file.md#abilities) in the [module.json5 configuration file](../quick-start/module-configuration-file.md). To enable an application to properly use a UIAbility component, declare the UIAbility name, entry, and label under [abilities](../quick-start/module-configuration-file.md#abilities) in the [module.json5 file](../quick-start/module-configuration-file.md).
```json ```json
......
# UIAbility Component Usage # UIAbility Usage
When using the UIAbility component, you must specify a startup page and obtain the context, [UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md). When using the UIAbility component, you must specify a startup page and obtain the context, [UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md).
...@@ -6,7 +6,7 @@ When using the UIAbility component, you must specify a startup page and obtain t ...@@ -6,7 +6,7 @@ When using the UIAbility component, you must specify a startup page and obtain t
## Specifying the Startup Page of UIAbility ## Specifying the Startup Page of UIAbility
If no startup page is specified, a white screen occurs after the application is started. You can use **loadContent()** of [WindowStage](../reference/apis/js-apis-window.md#windowstage9) to set the startup page in the **onWindowStageCreate()** callback of the UIAbility instance. You can use **loadContent()** of [WindowStage](../reference/apis/js-apis-window.md#windowstage9) to set the startup page in the **onWindowStageCreate()** callback of the UIAbility instance. If no startup page is specified, a white screen occurs after the application is started.
```ts ```ts
...@@ -27,7 +27,7 @@ export default class EntryAbility extends UIAbility { ...@@ -27,7 +27,7 @@ export default class EntryAbility extends UIAbility {
> **NOTE** > **NOTE**
> >
> When you create UIAbility in DevEco Studio, the UIAbility instance loads the **Index** page by default. Therefore, you only need to replace the **Index** page path with the required startup page path. > When you create UIAbility in DevEco Studio, the UIAbility instance loads the **Index** page as its startup page. Therefore, you only need to replace the **Index** page path with the required startup page path.
## Obtaining the Context of UIAbility ## Obtaining the Context of UIAbility
......
...@@ -115,7 +115,7 @@ To create a widget in the FA model, implement the widget lifecycle callbacks. Ge ...@@ -115,7 +115,7 @@ To create a widget in the FA model, implement the widget lifecycle callbacks. Ge
import formBindingData from '@ohos.app.form.formBindingData'; import formBindingData from '@ohos.app.form.formBindingData';
import formInfo from '@ohos.app.form.formInfo'; import formInfo from '@ohos.app.form.formInfo';
import formProvider from '@ohos.app.form.formProvider'; import formProvider from '@ohos.app.form.formProvider';
import dataStorage from '@ohos.data.storage'; import dataPreferences from '@ohos.data.preferences';
``` ```
2. Implement the widget lifecycle callbacks in **form.ts**. 2. Implement the widget lifecycle callbacks in **form.ts**.
...@@ -265,7 +265,7 @@ async function storeFormInfo(formId: string, formName: string, tempFlag: boolean ...@@ -265,7 +265,7 @@ async function storeFormInfo(formId: string, formName: string, tempFlag: boolean
"updateCount": 0 "updateCount": 0
}; };
try { try {
const storage = await dataStorage.getStorage(DATA_STORAGE_PATH); const storage = await dataPreferences.getPreferences(this.context, DATA_STORAGE_PATH);
// Put the widget information. // Put the widget information.
await storage.put(formId, JSON.stringify(formInfo)); await storage.put(formId, JSON.stringify(formInfo));
console.info(`storeFormInfo, put form info successfully, formId: ${formId}`); console.info(`storeFormInfo, put form info successfully, formId: ${formId}`);
...@@ -303,7 +303,7 @@ You should override **onDestroy** to implement widget data deletion. ...@@ -303,7 +303,7 @@ You should override **onDestroy** to implement widget data deletion.
const DATA_STORAGE_PATH = "/data/storage/el2/base/haps/form_store"; const DATA_STORAGE_PATH = "/data/storage/el2/base/haps/form_store";
async function deleteFormInfo(formId: string) { async function deleteFormInfo(formId: string) {
try { try {
const storage = await dataStorage.getStorage(DATA_STORAGE_PATH); const storage = await dataPreferences.getPreferences(this.context, DATA_STORAGE_PATH);
// Delete the widget information. // Delete the widget information.
await storage.delete(formId); await storage.delete(formId);
console.info(`deleteFormInfo, del form info successfully, formId: ${formId}`); console.info(`deleteFormInfo, del form info successfully, formId: ${formId}`);
......
...@@ -13,7 +13,7 @@ Widget switching involves the following parts: ...@@ -13,7 +13,7 @@ Widget switching involves the following parts:
| Configuration item location | **formAbility** and **forms** are in the **config.json** file.| **extensionAbilities** (configuration for **formExtensionAbility**) is in the **module.json5** file in the level-1 directory, and **forms** (configuration for **forms** contained in **formExtensionAbility**) is in the **form_config.json** file in the level-2 directory.| | Configuration item location | **formAbility** and **forms** are in the **config.json** file.| **extensionAbilities** (configuration for **formExtensionAbility**) is in the **module.json5** file in the level-1 directory, and **forms** (configuration for **forms** contained in **formExtensionAbility**) is in the **form_config.json** file in the level-2 directory.|
| Widget code path | Specified by **srcPath**, without the file name. | Specified by **srcEntry**, with the file name. | | Widget code path | Specified by **srcPath**, without the file name. | Specified by **srcEntry**, with the file name. |
| Programming language | **srcLanguage** can be set to **js** or **ets**. | This configuration item is unavailable. Only ets is supported. | | Programming language | **srcLanguage** can be set to **js** or **ets**. | This configuration item is unavailable. Only ets is supported. |
| Whether to enable widgets | formsEnabled | This configuration item is unavailable. The setting of **type** set to **form** means that the widgets are enabled. | | Whether to enable widgets | formsEnabled | This configuration item is unavailable. When **type** is set to **form**, widgets are enabled. |
| Ability type | type: service | type: form | | Ability type | type: service | type: form |
| Level-2 directory configuration tag| This configuration item is unavailable. | **metadata**, which consists of **name**, **value**, and **resource**, where **resource** points to the location of the **form_config.json** file in the level-2 directory.| | Level-2 directory configuration tag| This configuration item is unavailable. | **metadata**, which consists of **name**, **value**, and **resource**, where **resource** points to the location of the **form_config.json** file in the level-2 directory.|
......
# window Switching # window Switching
| API in the FA Model| Corresponding d.ts File in the Stage Model| Corresponding API in the Stage Model| | API in the FA Model| Corresponding .d.ts File in the Stage Model| Corresponding API in the Stage Model|
| -------- | -------- | -------- | | -------- | -------- | -------- |
| [create(id: string, type: WindowType, callback: AsyncCallback&lt;Window&gt;): void;](../reference/apis/js-apis-window.md#windowcreatedeprecated)<br>[create(id: string, type: WindowType): Promise&lt;Window&gt;;](../reference/apis/js-apis-window.md#windowcreatedeprecated-1) | \@ohos.window.d.ts | [createSubWindow(name: string, callback: AsyncCallback&lt;Window&gt;): void;](../reference/apis/js-apis-window.md#createsubwindow9)<br>[createSubWindow(name: string): Promise;](../reference/apis/js-apis-window.md#createsubwindow9-1)<br>An application developed on the FA model uses **window.create(id, WindowType.TYPE_APP)** to create a subwindow, whereas an application developed on the stage model uses **WindowStage.CreateSubWindow()** to create a subwindow.| | [create(id: string, type: WindowType, callback: AsyncCallback&lt;Window&gt;): void;](../reference/apis/js-apis-window.md#windowcreatedeprecated)<br>[create(id: string, type: WindowType): Promise&lt;Window&gt;;](../reference/apis/js-apis-window.md#windowcreatedeprecated-1) | \@ohos.window.d.ts | [createSubWindow(name: string, callback: AsyncCallback&lt;Window&gt;): void;](../reference/apis/js-apis-window.md#createsubwindow9)<br>[createSubWindow(name: string): Promise;](../reference/apis/js-apis-window.md#createsubwindow9-1)<br>An application developed on the FA model uses **window.create(id, WindowType.TYPE_APP)** to create a subwindow, whereas an application developed on the stage model uses **WindowStage.CreateSubWindow()** to create a subwindow.|
| [getTopWindow(callback: AsyncCallback&lt;Window&gt;): void;](../reference/apis/js-apis-window.md#windowgettopwindowdeprecated)<br>[getTopWindow(): Promise&lt;Window&gt;;](../reference/apis/js-apis-window.md#windowgettopwindowdeprecated-1) | \@ohos.window.d.ts | [getLastWindow(ctx: BaseContext, callback: AsyncCallback&lt;Window&gt;): void;](../reference/apis/js-apis-window.md#windowgetlastwindow9)<br>[getLastWindow(ctx: BaseContext): Promise&lt;Window&gt;;](../reference/apis/js-apis-window.md#windowgetlastwindow9-1) | | [getTopWindow(callback: AsyncCallback&lt;Window&gt;): void;](../reference/apis/js-apis-window.md#windowgettopwindowdeprecated)<br>[getTopWindow(): Promise&lt;Window&gt;;](../reference/apis/js-apis-window.md#windowgettopwindowdeprecated-1) | \@ohos.window.d.ts | [getLastWindow(ctx: BaseContext, callback: AsyncCallback&lt;Window&gt;): void;](../reference/apis/js-apis-window.md#windowgetlastwindow9)<br>[getLastWindow(ctx: BaseContext): Promise&lt;Window&gt;;](../reference/apis/js-apis-window.md#windowgetlastwindow9-1) |
# WindowExtensionAbility # WindowExtensionAbility (for System Applications Only)
[WindowExtensionAbility](../reference/apis/js-apis-application-windowExtensionAbility.md) is a type of ExtensionAbility component that allows a system application to be embedded in and displayed over another application. [WindowExtensionAbility](../reference/apis/js-apis-application-windowExtensionAbility.md) is a type of ExtensionAbility component that allows a system application to be embedded in and displayed over another application.
...@@ -11,19 +11,19 @@ the context is [WindowExtensionContext](../reference/apis/js-apis-inner-applicat ...@@ -11,19 +11,19 @@ the context is [WindowExtensionContext](../reference/apis/js-apis-inner-applicat
> **NOTE** > **NOTE**
> >
> **WindowExtensionAbility** is a system API. To embed a third-party application in another application and display it over the application, switch to the full SDK by following the instructions provided in [Guide to Switching to Full SDK](../faqs/full-sdk-switch-guide.md). > **WindowExtensionAbility** is a system API. To use it, switch to the full SDK by following the instructions provided in [Guide to Switching to Full SDK](../faqs/full-sdk-switch-guide.md).
> >
## Setting an Embedded UIAbility (for System Applications Only) ## Setting an Embedded UIAbility
The **WindowExtensionAbility** class provides **onConnect()**, **onDisconnect()**, and **onWindowReady()** lifecycle callbacks, which can be overridden. The **WindowExtensionAbility** class provides **onConnect()**, **onDisconnect()**, and **onWindowReady()** lifecycle callbacks, which can be overridden.
- The **onWindowReady()** callback is invoked when a window is created for the ability. - The **onWindowReady()** callback is invoked when a window is created for the UIAbility.
- The **onConnect()** callback is invoked when the AbilityComponent corresponding to the window connects to the ability. - The **onConnect()** callback is invoked when the AbilityComponent corresponding to the window connects to the UIAbility.
- The **onDisconnect()** callback is invoked when the AbilityComponent disconnects from the ability. - The **onDisconnect()** callback is invoked when the AbilityComponent disconnects from the UIAbility.
**How to Develop** **How to Develop**
...@@ -79,7 +79,7 @@ To implement an embedded application, manually create a WindowExtensionAbility i ...@@ -79,7 +79,7 @@ To implement an embedded application, manually create a WindowExtensionAbility i
``` ```
## Starting an Embedded UIAbility (for System Applications Only) ## Starting an Embedded UIAbility
System applications can load the created WindowExtensionAbility through the AbilityComponent. System applications can load the created WindowExtensionAbility through the AbilityComponent.
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
## Overview ## Overview
To accelerate test automation of OpenHarmony, arkXtest — an automated test framework that supports both the JavaScript (JS) and TypeScript (TS) programming languages — is provided. To accelerate test automation of OpenHarmony, arkXtest — an automated unit and UI test framework that supports both the JavaScript (JS) and TypeScript (TS) programming languages — is provided.
In this document you will learn about the key functions of arkXtest and how to use it to perform unit testing on application or system APIs and to write UI automated test scripts. In this document you will learn about the key functions of arkXtest and how to use it to perform unit testing on application or system APIs and to write UI automated test scripts.
...@@ -13,7 +13,7 @@ In this document you will learn about the key functions of arkXtest and how to u ...@@ -13,7 +13,7 @@ In this document you will learn about the key functions of arkXtest and how to u
arkXtest is part of the OpenHarmony toolkit and provides basic capabilities of writing and running OpenHarmony automated test scripts. In terms of test script writing, arkXtest offers a wide range of APIs, including basic process APIs, assertion APIs, and APIs related to UI operations. In terms of test script running, arkXtest offers such features as identifying, scheduling, and executing test scripts, as well as summarizing test script execution results. arkXtest is part of the OpenHarmony toolkit and provides basic capabilities of writing and running OpenHarmony automated test scripts. In terms of test script writing, arkXtest offers a wide range of APIs, including basic process APIs, assertion APIs, and APIs related to UI operations. In terms of test script running, arkXtest offers such features as identifying, scheduling, and executing test scripts, as well as summarizing test script execution results.
### Principles ### Implementation
arkXtest is divided into two parts: unit test framework and UI test framework. arkXtest is divided into two parts: unit test framework and UI test framework.
...@@ -27,16 +27,16 @@ arkXtest is divided into two parts: unit test framework and UI test framework. ...@@ -27,16 +27,16 @@ arkXtest is divided into two parts: unit test framework and UI test framework.
![](figures/TestFlow.PNG) ![](figures/TestFlow.PNG)
- UI Testing Framework - UI Test Framework
The UI test framework provides [UiTest APIs](../reference/apis/js-apis-uitest.md) for you to call in different test scenarios. The test scripts are executed on top of the unit test framework mentioned above. The UI test framework provides [UiTest APIs](../reference/apis/js-apis-uitest.md) for you to call in different test scenarios. The UI test scripts are executed on top of the aformentioned unit test framework.
The figure below shows the main functions of the UI test framework. The figure below shows the main functions of the UI test framework.
![](figures/Uitest.PNG) ![](figures/Uitest.PNG)
### Limitations and Constraints ### Constraints
- The features of the UI test framework are available only in OpenHarmony 3.1 and later versions. - The features of the UI test framework are available only in OpenHarmony 3.1 and later versions.
- The feature availability of the unit test framework varies by version. For details about the mappings between the features and versions, see [arkXtest](https://gitee.com/openharmony/testfwk_arkxtest/blob/master/README_en.md). - The feature availability of the unit test framework varies by version. For details about the mappings between the features and versions, see [arkXtest](https://gitee.com/openharmony/testfwk_arkxtest/blob/master/README_en.md).
...@@ -46,9 +46,9 @@ arkXtest is divided into two parts: unit test framework and UI test framework. ...@@ -46,9 +46,9 @@ arkXtest is divided into two parts: unit test framework and UI test framework.
### Environment Requirements ### Environment Requirements
Software for writing test scripts: DevEco Studio 3.0 or later Software: DevEco Studio 3.0 or later
Hardware for running test scripts: PC connected to an OpenHarmony device, such as the RK3568 development board Hardware: PC connected to an OpenHarmony device, such as the RK3568 development board
### Setting Up the Environment ### Setting Up the Environment
...@@ -57,7 +57,7 @@ Hardware for running test scripts: PC connected to an OpenHarmony device, such a ...@@ -57,7 +57,7 @@ Hardware for running test scripts: PC connected to an OpenHarmony device, such a
## Creating a Test Script ## Creating a Test Script
1. Open DevEco Studio and create a project, where the **ohos** directory is where the test script is located. 1. Open DevEco Studio and create a project, in which the **ohos** directory is where the test script is located.
2. Open the .ets file of the module to be tested in the project directory. Move the cursor to any position in the code, and then right-click and choose **Show Context Actions** > **Create Ohos Test** or press **Alt+Enter** and choose **Create Ohos Test** to create a test class. 2. Open the .ets file of the module to be tested in the project directory. Move the cursor to any position in the code, and then right-click and choose **Show Context Actions** > **Create Ohos Test** or press **Alt+Enter** and choose **Create Ohos Test** to create a test class.
## Writing a Unit Test Script ## Writing a Unit Test Script
...@@ -95,7 +95,7 @@ export default function abilityTest() { ...@@ -95,7 +95,7 @@ export default function abilityTest() {
The unit test script must contain the following basic elements: The unit test script must contain the following basic elements:
1. Import of the dependency package so that the dependent test APIs can be used. 1. Import of the dependencies so that the dependent test APIs can be used.
2. Test code, mainly about the related logic, such as API invoking. 2. Test code, mainly about the related logic, such as API invoking.
...@@ -105,7 +105,7 @@ The unit test script must contain the following basic elements: ...@@ -105,7 +105,7 @@ The unit test script must contain the following basic elements:
You write a UI test script based on the unit test framework, adding the invoking of APIs provided by the UI test framework to implement the corresponding test logic. You write a UI test script based on the unit test framework, adding the invoking of APIs provided by the UI test framework to implement the corresponding test logic.
In this example, the UI test script is written based on the preceding unit test script. First, add the dependency package, as shown below: In this example, the UI test script is written based on the preceding unit test script. First, import the dependency, as shown below:
```js ```js
import {Driver,ON,Component,MatchPattern} from '@ohos.uitest' import {Driver,ON,Component,MatchPattern} from '@ohos.uitest'
...@@ -158,11 +158,9 @@ export default function abilityTest() { ...@@ -158,11 +158,9 @@ export default function abilityTest() {
You can run a test script in DevEco Studio in any of the following modes: You can run a test script in DevEco Studio in any of the following modes:
1. Test package level: All test cases in the test package are executed. - Test package level: All test cases in the test package are executed.
- Test suite level: All test cases defined in the **describe** method are executed.
2. Test suite level: All test cases defined in the **describe** method are executed. - Test method level: The specified **it** method, that is, a single test case, is executed.
3. Test method level: The specified **it** method, that is, a single test case, is executed.
![](figures/Execute.PNG) ![](figures/Execute.PNG)
...@@ -176,7 +174,7 @@ After the test is complete, you can view the test result in DevEco Studio, as sh ...@@ -176,7 +174,7 @@ After the test is complete, you can view the test result in DevEco Studio, as sh
To run a test script in the CLI, execute **aa** commands with different execution control keywords. To run a test script in the CLI, execute **aa** commands with different execution control keywords.
Parameters in aa test commands The table below lists the keywords in **aa** test commands.
| Keyword | Abbreviation| Description | Example | | Keyword | Abbreviation| Description | Example |
| ------------- | ------------ | -------------------------------------- | ---------------------------------- | | ------------- | ------------ | -------------------------------------- | ---------------------------------- |
...@@ -187,18 +185,18 @@ Parameters in aa test commands ...@@ -187,18 +185,18 @@ Parameters in aa test commands
The framework supports multiple test case execution modes, which are triggered by the key-value pair following the **-s** keyword. The table below lists the available keys and values. The framework supports multiple test case execution modes, which are triggered by the key-value pair following the **-s** keyword. The table below lists the available keys and values.
| Key | Description | Value | Parameter | | Key | Description | Value | Example |
| ------------ | ----------------------------------------------------------------------------- | ------------------------------------------------------------ | ----------------------------------------- | | ------------ | ----------------------------------------------------------------------------- | ------------------------------------------------------------ | ----------------------------------------- |
| unittest | OpenHarmonyTestRunner object used for test case execution. | **OpenHarmonyTestRunner** or custom runner name. | - s unittest OpenHarmonyTestRunner | | unittest | **OpenHarmonyTestRunner** object used for test case execution. | **OpenHarmonyTestRunner** or custom runner name. | - s unittest OpenHarmonyTestRunner |
| class | Test suite or test case to be executed. | {describeName}#{itName}, {describeName} | -s class attributeTest#testAttributeIt | | class | Test suite or test case to be executed. | {describeName}#{itName}, {describeName} | -s class attributeTest#testAttributeIt |
| notClass | Test suite or test case that does not need to be executed. | {describeName}#{itName}, {describeName} | -s notClass attributeTest#testAttributeIt | | notClass | Test suite or test case that does not need to be executed. | {describeName}#{itName}, {describeName} | -s notClass attributeTest#testAttributeIt |
| itName | Test case to be executed. | {itName} | -s itName testAttributeIt | | itName | Test case to be executed. | {itName} | -s itName testAttributeIt |
| timeout | Timeout interval for executing a test case. | Positive integer (unit: ms). If no value is set, the default value 5000 is used. | -s timeout 15000 | | timeout | Timeout interval for executing a test case. | Positive integer (unit: ms). If no value is set, the default value 5000 is used. | -s timeout 15000 |
| breakOnError | Whether to enable break-on-error mode. When this mode is enabled, the test execution process exits if a test assertion error or any other error occurs.| **true**/**false** (default value) | -s breakOnError true | | breakOnError | Whether to enable break-on-error mode. When this mode is enabled, the test execution process exits if a test assertion failure or error occurs.| **true**/**false** (default value) | -s breakOnError true |
| random | Whether to execute test cases in random sequence.| **true**/**false** (default value) | -s random true | | random | Whether to execute test cases in random sequence.| **true**/**false** (default value) | -s random true |
| testType | Type of the test case to be executed. | function, performance, power, reliability, security, global, compatibility, user, standard, safety, resilience| -s testType function | | testType | Type of the test case to be executed. | function, performance, power, reliability, security, global, compatibility, user, standard, safety, resilience| -s testType function |
| level | Level of the test case to be executed. | 0, 1, 2, 3, 4 | -s level 0 | | level | Level of the test case to be executed. | 0, 1, 2, 3, 4 | -s level 0 |
| size | Size of the test case to be executed. | small, medium, large | -s size small | | size | Size of the test case to be executed. | small, medium, large | -s size small
| stress | Number of times that the test case is executed. | Positive integer | -s stress 1000 | | stress | Number of times that the test case is executed. | Positive integer | -s stress 1000 |
**Running Commands** **Running Commands**
...@@ -306,7 +304,7 @@ OHOS_REPORT_STATUS: consuming=4 ...@@ -306,7 +304,7 @@ OHOS_REPORT_STATUS: consuming=4
| OHOS_REPORT_STATUS: stream | Error information of the current test case.| | OHOS_REPORT_STATUS: stream | Error information of the current test case.|
| OHOS_REPORT_STATUS: test| Name of the current test case.| | OHOS_REPORT_STATUS: test| Name of the current test case.|
| OHOS_REPORT_STATUS_CODE | Execution result of the current test case. The options are as follows:<br>**0**: pass<br>**1**: error<br>**2**: fail| | OHOS_REPORT_STATUS_CODE | Execution result of the current test case. The options are as follows:<br>**0**: pass<br>**1**: error<br>**2**: fail|
| OHOS_REPORT_STATUS: consuming | Execution duration of the current test case.| | OHOS_REPORT_STATUS: consuming | Time spent in executing the current test case.|
- After the commands are executed, the log information similar to the following is displayed: - After the commands are executed, the log information similar to the following is displayed:
...@@ -324,7 +322,7 @@ OHOS_REPORT_STATUS: taskconsuming=16029 ...@@ -324,7 +322,7 @@ OHOS_REPORT_STATUS: taskconsuming=16029
| Failure | Number of failed test cases.| | Failure | Number of failed test cases.|
| Error | Number of test cases whose execution encounters errors. | | Error | Number of test cases whose execution encounters errors. |
| Pass | Number of passed test cases.| | Pass | Number of passed test cases.|
| Ignore | Number of test cases not executed.| | Ignore | Number of test cases not yet executed.|
| taskconsuming| Total time spent in executing the current test case.| | taskconsuming| Total time spent in executing the current test case.|
> When an error occurs in break-on-error mode, check the **Ignore** and interrupt information. > When an error occurs in break-on-error mode, check the **Ignore** and interrupt information.
...@@ -341,11 +339,11 @@ The logs added to the test case are displayed after the test case execution, rat ...@@ -341,11 +339,11 @@ The logs added to the test case are displayed after the test case execution, rat
**Possible Causes** **Possible Causes**
More than one asynchronous interface is called in the test case.<br>In principle, logs in the test case are printed before the test case execution is complete. More than one asynchronous API is called in the test case.<br>In principle, logs in the test case are printed before the test case execution is complete.
**Solution** **Solution**
If more than one asynchronous interface is called, you are advised to encapsulate the interface invoking into the promise mode If more than one asynchronous API is called, you are advised to encapsulate the API invoking into the promise mode.
#### Error "fail to start ability" is reported during test case execution #### Error "fail to start ability" is reported during test case execution
...@@ -373,7 +371,7 @@ After the test case execution is complete, the console displays the error messag ...@@ -373,7 +371,7 @@ After the test case execution is complete, the console displays the error messag
2. The time taken for API invocation is longer than the timeout interval set for test case execution. 2. The time taken for API invocation is longer than the timeout interval set for test case execution.
3. Test assertion fails, and a failure exception is thrown. As a result, the test case execution does not end until the timeout expires. 3. Test assertion fails, and a failure exception is thrown. As a result, the test case execution does not end until it times out.
**Solution** **Solution**
...@@ -388,11 +386,11 @@ After the test case execution is complete, the console displays the error messag ...@@ -388,11 +386,11 @@ After the test case execution is complete, the console displays the error messag
**Problem** **Problem**
The UI test case fails to be executed. The HiLog file contains the error message "Get windows failed/GetRootByWindow failed". The UI test case fails to be executed. The HiLog file contains the error message "Get windows failed/GetRootByWindow failed."
**Possible Causes** **Possible Causes**
The ArkUI feature is disabled. As a result, the control tree information on the test page is not generated. The ArkUI feature is disabled. As a result, the component tree information is not generated on the test page.
**Solution** **Solution**
...@@ -410,13 +408,13 @@ The UI test case fails to be executed. The HiLog file contains the error message ...@@ -410,13 +408,13 @@ The UI test case fails to be executed. The HiLog file contains the error message
**Possible Causes** **Possible Causes**
1. In the test case, the **await** operator is not added to the asynchronous interface provided by the UI test framework. 1. In the test case, the **await** operator is not added to the asynchronous API provided by the UI test framework.
2. The UI test case is executed in multiple processes. As a result, multiple UI test processes are started. The framework does not support multi-process invoking. 2. The UI test case is executed in multiple processes. As a result, multiple UI test processes are started. The framework does not support multi-process invoking.
**Solution** **Solution**
1. Check the case implementation and add the **await** operator to the asynchronous interface invoking. 1. Check the case implementation and add the **await** operator to the asynchronous API.
2. Do not execute UI test cases in multiple processes. 2. Do not execute UI test cases in multiple processes.
...@@ -424,11 +422,11 @@ The UI test case fails to be executed. The HiLog file contains the error message ...@@ -424,11 +422,11 @@ The UI test case fails to be executed. The HiLog file contains the error message
**Problem** **Problem**
The UI test case fails to be executed. The HiLog file contains the error message "does not exist on current UI! Check if the UI has changed after you got the widget object". The UI test case fails to be executed. The HiLog file contains the error message "does not exist on current UI! Check if the UI has changed after you got the widget object."
**Possible Causes** **Possible Causes**
After the target component is found in the code of the test case, the device UI changes. As a result, the found component is lost and the emulation operation cannot be performed. After the target component is found in the code of the test case, the device UI changes, resulting in loss of the found component and inability to perform emulation.
**Solution** **Solution**
......
...@@ -78,6 +78,8 @@ httpRequest.request( ...@@ -78,6 +78,8 @@ httpRequest.request(
// data.header carries the HTTP response header. Parse the content based on service requirements. // data.header carries the HTTP response header. Parse the content based on service requirements.
console.info('header:' + JSON.stringify(data.header)); console.info('header:' + JSON.stringify(data.header));
console.info('cookies:' + JSON.stringify(data.cookies)); // 8+ console.info('cookies:' + JSON.stringify(data.cookies)); // 8+
// Call the destroy() method to release resources after HttpRequest is complete.
httpRequest.destroy();
} else { } else {
console.info('error:' + JSON.stringify(err)); console.info('error:' + JSON.stringify(err));
// Unsubscribe from HTTP Response Header events. // Unsubscribe from HTTP Response Header events.
...@@ -158,4 +160,11 @@ httpRequest.request2( ...@@ -158,4 +160,11 @@ httpRequest.request2(
httpRequest.destroy(); httpRequest.destroy();
} }
); );
``` ```
\ No newline at end of file
## Samples
The following sample is provided to help you better understand how to develop the HTTP data request feature:
- [`Http`: Data Request (ArkTS) (API9)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Connectivity/Http)
- [HTTP Communication (ArkTS) (API9)](https://gitee.com/openharmony/codelabs/tree/master/NetworkManagement/SmartChatEtsOH)
# HiLog Development (Native) # HiLog Development (Native)
## Introduction ## Introduction
HiLog is the log system of OpenHarmony that provides logging for the system framework, services, and applications to record information on user operations and system running status. HiLog is the log system of OpenHarmony that provides logging for the system framework, services, and applications to record information on user operations and system running status.
...@@ -13,11 +13,11 @@ HiLog is the log system of OpenHarmony that provides logging for the system fram ...@@ -13,11 +13,11 @@ HiLog is the log system of OpenHarmony that provides logging for the system fram
| API/Macro| Description| | API/Macro| Description|
| -------- | -------- | | -------- | -------- |
| int OH_LOG_Print(LogType type, LogLevel level, unsigned int domain, const char *tag, const char *fmt, ...) | Outputs logs based on the specified log type, log level, service domain, log tag, and variable parameters determined by the format specifier and privacy identifier in the printf format.<br>Input arguments: See [Parameter Description](#parameter-description).<br>Output arguments: None<br>Return value: total number of bytes if log printing is successful; **-1** otherwise.| | int OH_LOG_Print(LogType type, LogLevel level, unsigned int domain, const char *tag, const char *fmt, ...) | Outputs logs based on the specified log type, log level, service domain, log tag, and variable parameters determined by the format specifier and privacy identifier in the printf format.<br>Input arguments: See [Parameter Description](#parameter-description).<br>Output arguments: None<br>Return value: total number of bytes if log printing is successful; **-1** otherwise.|
| #define OH_LOG_DEBUG(type, ...) ((void)OH_LOG_Print((type), LOG_DEBUG, LOG_DOMAIN, LOG_TAG, \_*VA*ARGS__))| Outputs DEBUG logs. This is a function-like macro.| | #define OH_LOG_DEBUG(type, ...) ((void)OH_LOG_Print((type), LOG_DEBUG, LOG_DOMAIN, LOG_TAG, \__VA_ARGS__))| Outputs DEBUG logs. This is a function-like macro.|
| #define OH_LOG_INFO(type, ...) ((void)OH_LOG_Print((type), LOG_INFO, LOG_DOMAIN, LOG_TAG, \_*VA*ARGS__)) | Outputs INFO logs. This is a function-like macro.| | #define OH_LOG_INFO(type, ...) ((void)OH_LOG_Print((type), LOG_INFO, LOG_DOMAIN, LOG_TAG, \__VA_ARGS__)) | Outputs INFO logs. This is a function-like macro.|
| #define OH_LOG_WARN(type, ...) ((void)OH_LOG_Print((type), LOG_WARN, LOG_DOMAIN, LOG_TAG, \_*VA*ARGS__)) | Outputs WARN logs. This is a function-like macro.| | #define OH_LOG_WARN(type, ...) ((void)OH_LOG_Print((type), LOG_WARN, LOG_DOMAIN, LOG_TAG, \__VA_ARGS__)) | Outputs WARN logs. This is a function-like macro.|
| #define OH_LOG_ERROR(type, ...) ((void)OH_LOG_Print((type), LOG_ERROR, LOG_DOMAIN, LOG_TAG, \_*VA*ARGS__)) | Outputs ERROR logs. This is a function-like macro.| | #define OH_LOG_ERROR(type, ...) ((void)OH_LOG_Print((type), LOG_ERROR, LOG_DOMAIN, LOG_TAG, \__VA_ARGS__)) | Outputs ERROR logs. This is a function-like macro.|
| #define OH_LOG_FATAL(type, ...) ((void)OH_LOG_Print((type), LOG_FATAL, LOG_DOMAIN, LOG_TAG, \_*VA*ARGS__)) | Outputs FATAL logs. This is a function-like macro.| | #define OH_LOG_FATAL(type, ...) ((void)OH_LOG_Print((type), LOG_FATAL, LOG_DOMAIN, LOG_TAG, \__VA_ARGS__)) | Outputs FATAL logs. This is a function-like macro.|
| bool OH_LOG_IsLoggable(unsigned int domain, const char *tag, LogLevel level) | Checks whether logs of the specified service domain, tag, and level can be printed.<br>Input arguments: See [Parameter Description](#parameter-description).<br>Output arguments: none<br>Return value: **true** if the specified logs can be printed; **false** otherwise.| | bool OH_LOG_IsLoggable(unsigned int domain, const char *tag, LogLevel level) | Checks whether logs of the specified service domain, tag, and level can be printed.<br>Input arguments: See [Parameter Description](#parameter-description).<br>Output arguments: none<br>Return value: **true** if the specified logs can be printed; **false** otherwise.|
## Parameter Description ## Parameter Description
...@@ -33,7 +33,7 @@ HiLog is the log system of OpenHarmony that provides logging for the system fram ...@@ -33,7 +33,7 @@ HiLog is the log system of OpenHarmony that provides logging for the system fram
## LogLevel ## LogLevel
Log level. Enumerates log levels.
| Name | Value | Description | | Name | Value | Description |
| ----- | ------ | ------------------------------------------------------------ | | ----- | ------ | ------------------------------------------------------------ |
......
...@@ -4,7 +4,12 @@ ...@@ -4,7 +4,12 @@
- [Switching to Full SDK](full-sdk-switch-guide.md) - [Switching to Full SDK](full-sdk-switch-guide.md)
- [Application Model Development](faqs-ability.md) - [Application Model Development](faqs-ability.md)
- ArkUI Framework Development (ArkTS) - ArkUI Framework Development (ArkTS)
- [ArkUI Development (ArkTS Syntax)](faqs-arkui-arkts.md) - [ArkTS Syntax Usage](faqs-arkui-arkts.md)
- [ArkUI Component Development (ArkTS)](faqs-arkui-component.md)
- [ArkUI Layout Development (ArkTS)](faqs-arkui-layout.md)
- [ArkUI Routing/Navigation Development (ArkTS)](faqs-arkui-route-nav.md)
- [ArkUI Animation/Interaction Event Development (ArkTS)](faqs-arkui-animation-interactive-event.md)
- [ArkUI Development (JS)](faqs-arkui-js.md)
- [Web Development](faqs-arkui-web.md) - [Web Development](faqs-arkui-web.md)
- [Bundle Management Development](faqs-bundle-management.md) - [Bundle Management Development](faqs-bundle-management.md)
- [Resource Manager Development](faqs-globalization.md) - [Resource Manager Development](faqs-globalization.md)
...@@ -22,4 +27,5 @@ ...@@ -22,4 +27,5 @@
- [Startup Development](faqs-startup.md) - [Startup Development](faqs-startup.md)
- [Distributed Device Development](faqs-distributed-device-profile.md) - [Distributed Device Development](faqs-distributed-device-profile.md)
- [SDK Usage](faqs-sdk.md) - [SDK Usage](faqs-sdk.md)
- [Compiler Runtime](faqs-compiler-runtime.md)
- [Usage of Third- and Fourth-Party Libraries](faqs-third-fourth-party-library.md) - [Usage of Third- and Fourth-Party Libraries](faqs-third-fourth-party-library.md)
\ No newline at end of file
# Ability Access Control Development # Application Access Control Development
## Can the app listen for the permission change after its permission is modified in Settings? ## Can the app listen for the permission change after its permission is modified in Settings?
Applicable to: OpenHarmony 3.1 Beta 5 (API version 9) Applicable to: OpenHarmony 3.1 Beta 5 (API version 9)
Third-party apps cannot listen for the permission change. Third-party apps cannot listen for the permission change.
## Why is there no pop-up window displayed when an app applies for the **ohos.permission.LOCATION** permission?
Applicable to: OpenHarmony 3.2 Release (API version 9)
Applications developed using SDKs earlier than API version 9 can directly apply for the **ohos.permission.LOCATION** permission.
For the applications developed using the SDK of API version 9 or later, you need to apply for **ohos.permission.APPROXIMATELY_LOCATION** and then **ohos.permission.LOCATION**.
**References**
[Application Permission List](../security/permission-list.md#ohospermissionlocation)
## What can I do to prevent the application from crashing when the application is started again after the user denies the permission requested?
Applicable to: OpenHarmony SDK 3.2 Beta5
**Possible Causes**
- If the permission required by a service is rejected by the user, the system directly returns the result and will no longer display a dialog box to request the permission.
- If related judgment is not performed after the permission is requested, the application will be rejected due to lack of the corresponding permission when accessing the target object under permission control, and terminated unexpectedly.
**Solution**
1. Before allowing an application to call an API protected by certain permission, verify whether the application has the permission. If the application has the permission, the application can call the API. Otherwise, a dialog box is dipslayed to ask user authorization.
2. If the user rejects to grant the permission, ensure that other functions irrelevant to this permission are not affected.
3. When this service is triggered again by the user or to implement a service function, on-screen message shall be provided to guide the user to grant the permission in **Settings**.
**References**
[Access Control (Permission) Overview](../security/accesstoken-overview.md)
## What are the differences between **extensionAbilities** and **requestPermissions** in the **module.json5** file?
Applicable to: OpenHarmony SDK 3.2 Beta5
- **requestPermissions**: specifies all the permissions required by an application for running. The permissions take effect only after being configured (declared) in the **module.json5** file.
- **extensionAbilitie.permissions**: specifies the permissions customized by the ExtensionAbility component. These permissions are required when an application needs to access the ExtensionAbility component. **extensionAbilitie.permissions** is used for permission verification only.
**References**
[module.json5 Configuration File](../quick-start/module-configuration-file.md)
# ArkUI Animation/Interaction Event Development (ArkTS)
## What should I do if the onBlur and onFocus callbacks cannot be triggered?
Applicable to: OpenHarmony 3.2 Beta 5 (API version 9)
**Symptom**
The **onBlur** and **onFocus** callbacks of the focus event cannot be triggered.
**Solution**
Check the trigger device. By default, the focus event (and the **onBlur** and **onFocus** callbacks) can be triggered only by the Tab button and arrow buttons on the connected keyboard. To enable the focus event to be triggered by a touch, add the **focusOnTouch** attribute for the target component.
**Reference**
[Focus Control](../reference/arkui-ts/ts-universal-attributes-focus.md)
## How do I disable the scroll event of a \<Grid> nested in the \<Scroll>?
Applicable to: OpenHarmony 3.2 Beta 5 (API version 9)
Implement nested scrolling of the containers, by using the **onScrollFrameBegin** event and the **scrollBy** method.
**Reference**
[Scroll](../reference/arkui-ts/ts-container-scroll.md#example-2)
## How do I enable a component to rotate continuously?
Applicable to: OpenHarmony 3.2 Beta 5 (API version 9)
You can use [attribute animation](../reference/arkui-ts/ts-animatorproperty.md) to that effect.
## How do I scroll a list with the keyboard?
Applicable to: OpenHarmony 3.2 Beta 5 (API version 9)
**Solution**
- Add **focusable\(true\)** to the list item to enable it to obtain focus.
- Nest a focusable component, for example, **\<Button>**, at the outer layer of each item.
## Why is the click event not triggered for the focused component upon the press of the Enter key after keyboard navigation?
Applicable to: OpenHarmony 3.2 Beta 5 (API version 9)
By default, the built-in click event of the component and the custom **onClick** click event are bound to the space bar instead of the Enter key.
## How do I block event bubbling when a button is nested in multi-layer components?
Applicable to: OpenHarmony 3.2 Beta 5 (API version 9)
You can bind the button to the **stopPropagation** parameter.
## How do I disable the transition effect between pages when the router or navigator is used to switch between pages?
Applicable to: OpenHarmony 3.2 Beta 5 (API version 9)
1. Define the **pageTransition** method for the current and target pages, by following instructions in [Example](../reference/arkui-ts/ts-page-transition-animation.md#example).
2. Set the **duration** parameter of both **PageTransitionEnter** and **PageTransitionExit** to **0**.
## How do I fix misidentification of the pan gesture where container nesting is involved?
Applicable to: OpenHarmony 3.2 Beta 5 (API version 9)
The pan gesture requires a minimum 5 vp movement distance of a finger on the screen. You can set the **distance** parameter in **PanGesture** to **1** so that the pan gesture can be more easily recognized.
**Reference**
[PanGesture](../reference/arkui-ts/ts-basic-gestures-pangesture.md)
## Can I use the fontFamily attribute to set different fonts for OpenHarmony applications?
Applicable to: OpenHarmony 3.2 Beta5 (API version 9)
No. For applications developed based on OpenHarmony, only the default font, HarmonyOS Sans, is supported.
## How do I implement a text input box that shows a soft keyboard when touched and hides the soft keyboard when a button is touched?
Applicable to: OpenHarmony 3.2 Beta 5 (API version 9)
Use **focusControl** for the **\<TextInput>** component to control its focus. The **\<TextInput>** component shows a soft keyboard when it gains focus and hides the soft keyboard when it loses focus.
**Example**
```
build() {
Column() {
TextInput()
Button(`hide`)
.key('button')
.onClick(()=>{
focusControl.requestFocus('button')
})
}
}
```
## How do I implement a button that only responds to the bound onClick event, but not the onTouch event bound to the button's parent component?
Applicable to: OpenHarmony 3.2 Beta 5 (API version 9)
Bind **onTouch** to the **\<Button>** component and use **stopPropagation\(\)** in **onTouch** to prevent **onTouch** from bubbling up to the parent component.
**Example**
```
build() {
Row() {
Button ("Click Me")
.width(100)
.width(100)
.backgroundColor('#f00')
.onClick(()=>{
console.log("Button onClick")
})
.onTouch((e) => {
console.log("Button onTouch")
e.stopPropagation()
})
}
.onTouch(() => {
console.log("Row onTouch")
})
}
```
## Why is the menu bound to a component not displayed by a right-click on the component?
Applicable to: OpenHarmony 3.2 Beta (API version 9)
**Solution**
Currently, the menu is displayed when the bound component is clicked or long pressed.
## How do I shield the default keyboard popup behavior of the \<TextInput> component?
Applicable to: OpenHarmony 3.2 Beta5 (API version 9)
Set the **focusable** attribute of the **\<TextInput>** component to **false**. In this way, the component is not focusable and therefore will not bring up the keyboard.
## How do I implement the slide up and slide down effect for page transition?
Applicable to: OpenHarmony 3.2 Beta5 (API version 9)
**Solution**
You can use the **pageTransition** API to implement the page transition effect. Specifically, set the **slide** attribute in **PageTransitionEnter** and **PageTransitionExit** to **SlideEffect.Bottom**. In this way, the page slides in and out from the bottom.
**Example**
```
// Index.ets
@Entry
@Component
struct PageTransition1 {
build() {
Stack({alignContent: Alignment.Bottom}) {
Navigator({ target: 'pages/Page1'}) {
Image($r('app.media.ic_banner01')).width('100%').height(200) // Save the image in the media folder.
}
}.height('100%').width('100%')
}
pageTransition() {
PageTransitionEnter({ duration: 500, curve: Curve.Linear }).slide(SlideEffect.Bottom)
PageTransitionExit({ duration: 500, curve: Curve.Ease }).slide(SlideEffect.Bottom)
}
}
```
```
// Page1.ets
@Entry
@Component
struct PageTransition2 {
build() {
Stack({alignContent: Alignment.Bottom}) {
Navigator({ target: 'pages/Index'}) {
Image($r('app.media.ic_banner02')).width('100%').height(200) // Save the image in the media folder.
}
}.height('100%').width('100%')
}
pageTransition() {
PageTransitionEnter({ duration: 500, curve: Curve.Linear }).slide(SlideEffect.Bottom)
PageTransitionExit({ duration: 500, curve: Curve.Ease }).slide(SlideEffect.Bottom)
}
}
```
**Reference**
[Page Transition Animation](../ui/arkts-page-transition-animation.md)
## How do I configure custom components to slide in and out from the bottom?
Applicable to: OpenHarmony 3.2 Beta5 (API version 9)
**Symptom**
Custom components A and B need to deliver the following effects: When custom component A, displayed at the bottom of the screen by default, is touched, it is hidden, and custom component B slides in from the bottom. When custom component B is touched, it is hidden, and custom component A slides in from the bottom.
**Solution**
You can use the **transition** attribute to create component transition animations. Set the **type** parameter to specify the component transition type, which can be component addition, component deletion, or both. Set the **translate** parameter to specify the translation of the component during transition. **NOTE**<br>The **transition** attribute must work with **animateTo**. The animation duration, curve, and delay follow the settings in **animateTo**.
**Example**
```
@Entry
@Component
struct ComponentTransition {
@State flag: boolean = true;
build() {
Stack({alignContent: Alignment.Bottom}) {
if (this.flag) {
ComponentChild1({ flag: $flag })
.transition({ type: TransitionType.Insert,translate: { x: 0, y: 200 } })
}
if (!this.flag) {
ComponentChild2({ flag: $flag })
.transition({ type: TransitionType.Insert, translate: { x: 0, y: 200 } })
}
}.height('100%').width('100%')
}
}
@Component
struct ComponentChild1 {
@Link flag: boolean
build() {
Column() {
Image($r('app.media.ic_banner01'))
.width('100%')
.height(200)
.onClick(() => {
animateTo({ duration: 1000 }, () => {
this.flag = !this.flag;
})
})
}
}
}
@Component
struct ComponentChild2 {
@Link flag: boolean
build() {
Column() {
Image($r('app.media.ic_banner02'))
.width('100%')
.height(200)
.onClick(() => {
animateTo({ duration: 1000 }, () => {
this.flag = !this.flag;
})
})
}
}
}
```
**Reference**
[Transition Animation Within the Component](../ui/arkts-transition-animation-within-component.md)
# ArkUI Development (ArkTS Syntax) # ArkTS Syntax Usage
## How do I dynamically create components using code in ArkUI? ## How do I dynamically create components using code in ArkUI?
...@@ -522,7 +522,7 @@ Applicable to: OpenHarmony 3.2 Beta 5 (API version 9) ...@@ -522,7 +522,7 @@ Applicable to: OpenHarmony 3.2 Beta 5 (API version 9)
**Reference** **Reference**
[Resource Categories and Access](../quick-start/resource-categories-and-access.md) and [@ohos.resourceManager (Resource Manager)](../reference/apis/js-apis-resource-manager.md#getstring) [Resource Categories and Access](../quick-start/resource-categories-and-access.md) and [@ohos.resourceManager (Resource Manager)](../reference/apis/js-apis-resource-manager.md)
## How do I convert the XML format to the JSON format? ## How do I convert the XML format to the JSON format?
......
# ArkUI Development (JS)
## Why can't array variables be used to control component attributes?
Applicable to: OpenHarmony (DevEco Studio 3.0.0.993, API version 8)
Currently, the web-like development paradigm does not listen for the modification of elements in an array. Therefore, the page refresh can be triggered only when the array object is modified, but not when an element in the array is modified. In the following example, the **test1\(\)** statement, which assigns values to the entire array, will disable the related **\<Button>** component; in contrast, the **test2\(\)** statement, which assigns a value to an element in the array, will not disable the **\<Button>** component. In addition to **test1\(\)**, you can also use the method of modifying the array, for example, **splice\(\)**, to trigger the page refresh.
```
test1() {this.isDisabled = [true, true, true, true, true]; // This statement disables the <Button> component.
test2() {this.isDisabled[0] = true; // This statement does not work for the <Button> component.
```
## Does the \<input> component support center alignment?
Applicable to: OpenHarmony 3.2 Beta5 (API version 9, FA model)
**Symptom**
The **text-align** style does not work for the **\<input>** component.
**Solution**
The **text-align** style works for the **\<text>** component, but not for the **\<input>** component.
**Reference**
[input](../reference/arkui-js/js-components-basic-input.md), [text](../reference/arkui-js/js-components-basic-text.md)
## How do I determine whether a value exists in a JS object?
Applicable to: OpenHarmony 3.2 Release (API version 9)
**Solution**
Use **Object.values\(*object name*\).indexOf\(*value to be checked*\)**. If **-1** is returned, the corresponding value is not included. Otherwise, the corresponding value is included.
# ArkUI Layout Development (ArkTS)
## What should I do if the height settings in position do not take effect?
Applicable to: OpenHarmony 3.2 Beta 5 (API version 9)
**Solution**
When **position** is set for a container component, it is taken out of normal flow and works independently from the outer container. In this case, the height does not take effect. You can replace the outer container with a stack to solve this issue.
## How do I implement horizontal scrolling on a \<Grid> component?
Applicable to: OpenHarmony 3.2 Beta 5 (API version 9)
Set **rowsTemplate** (the number of rows) for the **\<Grid>** component and do not set **columnsTemplate** (the number of columns). In this way, the **\<Grid>** component scrolls horizontally when its content does not fit within its width.
## What should I do if the \<List> component cannot be dragged to the bottom when it is used with another component and does not have the size specified?
Applicable to: OpenHarmony 3.2 Beta 5 (API version 9)
Add the **layoutWeight** attribute for the **\<List>** component so that it takes up the remaining height (or width, depending on the scrolling direction) adapatively.
By default, the **\<List>** component, as a scrollable container, takes up the entire screen height. When it is used with any component whose height is fixed, you need to explicitly add the **layoutWeight** attribute for the **\<List>** component so that it takes up the remaining height instead of the entire screen height.
## Can tab switching be disabled for the \<Tabs> component?
Applicable to: OpenHarmony 3.2 Release (API version 9)
No. This feature is not supported.
## How do I intercept the onBackPress event so that it does not trigger page return?
Applicable to: OpenHarmony 3.2 Release (API version 9)
If **true** is returned in **onBackPress**, the page executes its own return logic instead of the default return logic.
**Reference**
[onBackPress](../reference/arkui-ts/ts-custom-component-lifecycle.md#onbackpress).
## How do I implement a sticky header for a list item group in the \<List> component?
Applicable to: OpenHarmony 3.2 Release (API version 9)
You can use the **sticky** attribute of the **\<List>** component together with the **\<ListItemGroup>** component. Specifically, set the **sticky** attribute of the **\<List>** component to **StickyStyle.Header** and set the **header** parameter of the corresponding **\<ListItemGroup>** component.
**Reference**
[Adding a Sticky Header](../ui/arkts-layout-development-create-list.md#adding-a-sticky-header)
\ No newline at end of file
# ArkUI Routing/Navigation Development (ArkTS)
## Why can't class objects be transferred through params in the router API?
Applicable to: OpenHarmony 3.2 Beta5 (API version 9, stage model)
Only attributes in an object can be transferred, and methods in the object cannot.
## How do I use router to implement page redirection in the stage model?
Applicable to: OpenHarmony 3.2 Beta5 (API version 9, stage model)
1. To implement page redirection through **router**, add all redirected-to pages to the **pages** list in the **main\_pages.json** file.
2. Page routing APIs in **router** can be invoked only after page rendering is complete. Do not call these APIs in **onInit** or **onReady** when the page is still in the rendering phase.
**Reference**
[@ohos.router (Page Routing)](../reference/apis/js-apis-router.md)
## Will a page pushed into the stack through router.push be reclaimed?
Applicable to: OpenHarmony 3.2 Beta5 (API version 9, stage model)
After being pushed to the stack through **router.push**, a page can be reclaimed only when it is popped from the stack through **router.back**.
**Reference**
[router.getParams](../reference/apis/js-apis-router.md#routergetparams)
\ No newline at end of file
# Compiler Runtime
## What if a crash occurs when I obtain a string in JSON format from rawfile, convert the string into an object, and call the instance method?
Applicable to: OpenHarmony 3.2 Beta (API version 9)
**Symptom**
"jscrash happened in xxxxxxxxx" is displayed, and the crash log contains "Error message: Unexpected Object in JSON".
**Solution**
The prototype of the object obtained by parsing the string in JSON format is object. The prototype chain does not contain the instance method. Therefore, the object cannot be called.
To solve this problem, use either of the following methods:
1. Add the prototype to the parsed object.
2. Change the instance method to a static method and call it through the class name.
...@@ -25,8 +25,6 @@ An error is reported when the **TRUNCATE TABLE** statement is used to clear tabl ...@@ -25,8 +25,6 @@ An error is reported when the **TRUNCATE TABLE** statement is used to clear tabl
The RDB store uses SQLite and does not support the **TRUNCATE TABLE** statement. To clear a table in an RDB store, use the **DELETE** statement, for example, **DELETE FROM sqlite\_sequence WHERE name = 'table\_name'**. The RDB store uses SQLite and does not support the **TRUNCATE TABLE** statement. To clear a table in an RDB store, use the **DELETE** statement, for example, **DELETE FROM sqlite\_sequence WHERE name = 'table\_name'**.
## What data types does an RDB store support? ## What data types does an RDB store support?
Applicable to: OpenHarmony SDK 3.0 or later, API version 9 stage model Applicable to: OpenHarmony SDK 3.0 or later, API version 9 stage model
...@@ -35,13 +33,43 @@ Applicable to: OpenHarmony SDK 3.0 or later, API version 9 stage model ...@@ -35,13 +33,43 @@ Applicable to: OpenHarmony SDK 3.0 or later, API version 9 stage model
An RDB store supports data of the number, string, and Boolean types. The number type supports data of the Double, Long, Float, Int, or Int64 type, with a maximum precision of 17 decimal digits. An RDB store supports data of the number, string, and Boolean types. The number type supports data of the Double, Long, Float, Int, or Int64 type, with a maximum precision of 17 decimal digits.
## How do I save pixel map data to a database? ## How do I persist application data?
Applicable to: OpenHarmony 3.2 Beta 5 (API version 9) Applicable to: OpenHarmony 3.2 Beta 5 (API version 9)
**Symptom** **Solution**
You can use the **PersistentStorage** class to implement application data persistence. You can link the persistent data with specific tags to **AppStorage**, and invoke **AppStorage** APIs to access the persistent data. Persistent data is stored in a local XML file in **/data/app/el2/100/base/<bundleName\>/haps/<hapName\>/files/persistent\_storage**.
Example:
```
AppStorage.Link('varA')
PersistentStorage.PersistProp("varA", "111");
@Entry
@Component
struct Index {
@StorageLink('varA') varA: string = ''
build() {
Column() {
Text('varA: ' + this.varA).fontSize(20)
Button('Set').width(100).height(100).onClick(() => {
this.varA += '333'
})
}
.width('100%')
.height('100%')
}
}
```
**Reference**
[Persistent Data Management\(OpenHarmony\)](../quick-start/arkts-persiststorage.md)
## How do I save pixel map data to a database?
Pixel map data fails to be stored. Applicable to: OpenHarmony 3.2 Beta 5 (API version 9)
**Solution** **Solution**
...@@ -55,6 +83,10 @@ Convert the pixel map data into an **ArrayBuffer** and save the **ArrayBuffer** ...@@ -55,6 +83,10 @@ Convert the pixel map data into an **ArrayBuffer** and save the **ArrayBuffer**
Applicable to: OpenHarmony 3.2 Beta 5 (API version 9) Applicable to: OpenHarmony 3.2 Beta 5 (API version 9)
**Symptom**
Problem of obtaining RDB store files.
**Solution** **Solution**
The RDB store files are stored in **/data/app/el2/100/database/*Bundle_name*/entry/rdb/**. You can use the hdc command to copy the file from the directory and use a SQLite tool to open the file. The RDB store files are stored in **/data/app/el2/100/database/*Bundle_name*/entry/rdb/**. You can use the hdc command to copy the file from the directory and use a SQLite tool to open the file.
...@@ -69,6 +101,10 @@ Example: ...@@ -69,6 +101,10 @@ Example:
Applicable to: OpenHarmony 3.2 Beta 5 (API version 9) Applicable to: OpenHarmony 3.2 Beta 5 (API version 9)
**Symptom**
I do not know whether I need to design a lock mechanism for databases in development.
**Solution** **Solution**
The distributed data service (DDS), RDB store, and preferences provided OpenHarmony have a lock mechanism. You do not need to bother with the lock mechanism during the development. The distributed data service (DDS), RDB store, and preferences provided OpenHarmony have a lock mechanism. You do not need to bother with the lock mechanism during the development.
...@@ -97,5 +133,26 @@ In API version 8, large text files cannot be saved in RDB stores. ...@@ -97,5 +133,26 @@ In API version 8, large text files cannot be saved in RDB stores.
**Solution** **Solution**
In versions earlier than API version 9, the maximum length of a text file is 1024 bytes. If the text file exceeds 1024 bytes, it cannot be saved. In versions earlier than API version 9, the maximum length of a text file is 1024 bytes. If the text file exceeds 1024 bytes, it cannot be saved.
The limit on the text file size has been removed since API9 version. The limit on the text file size has been removed since API9 version.
## What if **undefined** is returned by **Preferences.get** after **Preferences.put()** is successfully called?
Applicable to: OpenHarmony 3.2 Beta 5 (API version 9)
**Symptom**
Data is successfully saved using **preferences**, but fails to be obtained.
**Solution**
1. After **put()** is performed, use **flush()** to persist the data.
2. Wait until the **flush()** asynchronous operation is complete, and call **get()**.
## Can I specify the in-memory database mode when using an RDB store?
Applicable to: OpenHarmony 3.2 Beta 5 (API version 9)
**Solution**
RDB stores use SQLite. The default in-memory database mode is file, which cannot be modified.
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
## How do I obtain the path of system screenshots? ## How do I obtain the path of system screenshots?
Applicable to: OpenHarmony 3.2 Beta 5 (API version 9) Applicable to: OpenHarmony 3.2 Beta5 (API version 9)
**Solution** **Solution**
...@@ -10,7 +10,7 @@ The screenshots are stored in **/storage/media/100/local/files/Pictures/Screensh ...@@ -10,7 +10,7 @@ The screenshots are stored in **/storage/media/100/local/files/Pictures/Screensh
## How do I change the permissions on a directory to read/write on a device? ## How do I change the permissions on a directory to read/write on a device?
Applicable to: OpenHarmony 3.2 Beta 5 (API version 9) Applicable to: OpenHarmony 3.2 Beta5 (API version 9)
**Symptom** **Symptom**
...@@ -19,3 +19,94 @@ When the hdc command is used to send a file to a device, "permission denied" is ...@@ -19,3 +19,94 @@ When the hdc command is used to send a file to a device, "permission denied" is
**Solution** **Solution**
Run the **hdc shell mount -o remount,rw /** command to grant the read/write permissions. Run the **hdc shell mount -o remount,rw /** command to grant the read/write permissions.
## What is the best way to create a file if the file to open does not exist?
Applicable to: OpenHarmony 3.2 (API version 9)
**Solution**
Use **fs.open(path: string, mode?: number)** with **mode** set to **fs.OpenMode.CREATE**. **fs.OpenMode.CREATE** creates a file if it does not exist.
## How do I solve the problem of garbled Chinese characters in a file?
Applicable to: OpenHarmony 3.2 (API version 9)
**Solution**
After the buffer data of the file content is read, use **TextDecoder** of @ohos.util to decode the file content.
```
let filePath = getContext(this).filesDir + "/test0.txt";
let stream = fs.createStreamSync(filePath, "r+");
let buffer = new ArrayBuffer(4096)
let readOut = stream.readSync(buffer);
let textDecoder = util.TextDecoder.create('utf-8', { ignoreBOM: true })
let readString = textDecoder.decodeWithStream(new Uint8Array(buffer), { stream: false });
console.log ("File content read: "+ readString);
```
## Why is an error reported when **fs.copyFile** is used to copy a **datashare://** file opened by **fs.open()**?
Applicable to: OpenHarmony 3.2 (API version 9)
**Solution**
**fs.copyFile** does not support URIs. You can use **fs.open()** to obtain the URI, obtain the file descriptor (FD) based on the URI, and then use **fs.copyFile** to copy the file based on the FD.
```
let file = fs.openSync("datashare://...")
fs.copyFile(file.fd, 'dstPath', 0).then(() => {
console.info('copyFile success')
}).catch((err) => {
console.info("copy file failed with error message: " + err.message + ", error code: " + err.code);
})
```
## How do I modify the specified content of a JSON file in the sandbox?
Applicable to: OpenHarmony 3.2 (API version 9)
**Solution**
Perform the following steps:
1. Use **fs.openSyn** to obtain the FD of the JSON file.
```
import fs from '@ohos.file.fs';
let sanFile = fs.open(basePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
let fd = sanFile.fd;
```
2. Use **fs.readSync** to read the file content.
```
let content = fs.readSync(basePath);
```
3. Modify the file content.
```
obj.name = 'new name';
```
4. Write the JSON file again.
```
fs.writeSync(file.fd, JSON.stringify(obj));
```
For more information, see [@ohos.file.fs](../reference/apis/js-apis-file-fs.md).
## What is the actual path corresponding to the file path obtained through the FileAccess module?
Applicable to: OpenHarmony 3.2 (API version 9, stage model)
**Solution**
The files are stored in the **/storage/media/100/local/files** directory. The specific file path varies with the file type and source. To obtain the actual file path, run the following command in the **/storage/media/100/local/files** directory:
**-name \[filename\]**
For more information, see [Uploading and Downloading an Application File](../file-management/app-file-upload-download.md).
...@@ -114,7 +114,7 @@ In effect, the **isStatusBarLightIcon** and **isNavigationBarLightIcon** attribu ...@@ -114,7 +114,7 @@ In effect, the **isStatusBarLightIcon** and **isNavigationBarLightIcon** attribu
**Reference** **Reference**
[window.SystemBarProperties](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-window.md#systembarproperties) [window.SystemBarProperties](../reference/apis/js-apis-window.md#systembarproperties)
## How do I keep the screen always on? ## How do I keep the screen always on?
......
...@@ -10,13 +10,17 @@ ...@@ -10,13 +10,17 @@
- [Obtaining Application and File System Space Statistics](app-fs-space-statistics.md) - [Obtaining Application and File System Space Statistics](app-fs-space-statistics.md)
- [Sending Files to an Application Sandbox](send-file-to-app-sandbox.md) - [Sending Files to an Application Sandbox](send-file-to-app-sandbox.md)
- [Sharing an Application File](share-app-file.md) - [Sharing an Application File](share-app-file.md)
- Application Data Backup and Restoration
- [Application Data Backup and Restoration Overview](app-file-backup-overview.md)
- [Backing Up and Restoring Application Access Data](app-file-backup-extension.md)
- [Backing Up and Restoring Application-triggered Data (for System Applications Only)](app-file-backup.md)
- User File - User File
- [User File Overview](user-file-overview.md) - [User File Overview](user-file-overview.md)
- Selecting and Saving User Files (FilePicker) - Selecting and Saving User Files (FilePicker)
- [Selecting User Files](select-user-file.md) - [Selecting User Files](select-user-file.md)
- [Saving User Files](save-user-file.md) - [Saving User Files](save-user-file.md)
- [Developing a FileManager Application (Available Only for System Applications)](dev-user-file-manager.md) - [Developing a FileManager Application (for System Applications Only)](dev-user-file-manager.md)
- [Managing External Storage Devices (Available Only for System Applications)](manage-external-storage.md) - [Managing External Storage Devices (for System Applications Only)](manage-external-storage.md)
- Distributed File System - Distributed File System
- [Distributed File System Overview](distributed-fs-overview.md) - [Distributed File System Overview](distributed-fs-overview.md)
- [Setting the Security Level of a Distributed File](set-security-label.md) - [Setting the Security Level of a Distributed File](set-security-label.md)
......
# Backing Up and Restoring Application Access Data
You can use BackupExtensionAbility to implement backup and restoration of application access data.
BackupExtensionAbility is a class derived from the [ExtensionAbility](../application-models/extensionability-overview.md) component in [Stage Model](../../application-dev/application-models/stage-model-development-overview.md). You can modify the configuration file to customize the behavior of the backup and restoration framework, including whether backup and restoration are allowed and which files are backed up.
## Constraints
- The paths of all files and directories to be backed up cannot exceed 4095 bytes. Otherwise, undefined behavior may occur.
- If a directory needs to be backed up, the application process must have the permission to read the directory and all its subdirectories (**r** in DAC). Otherwise, the backup fails.
- If a file needs to be backed up, the application process must have the permission to search for its grandparent directory of the file (**x** in DAC). Otherwise, the backup fails.
## How to Develop
1. Add the **extensionAbilities** configuration in the application's **module.json5** file.
Add **extensionAbilities**, set **type** to **backup**, and add **name: ohos.extension.backup** to **[metadata]**(../../application-dev/reference/apis/js-apis-bundleManager-metadata.md).
BackupExtensionAbility configuration example:
```json
{
"extensionAbilities": [
{
"description": "$string:ServiceExtAbility",
"icon": "$media:icon",
"name": "BackupExtensionAbility",
"type": "backup",
"visible": true,
"metadata": [
{
"name": "ohos.extension.backup",
"resource": "$profile:backup_config"
}
],
"srcEntrance": "",
}
]
}
```
2. Add a metadata resource configuration file.
The metadata resource configuration file defines the files to be transferred during backup and restoration. The file name must be the same as the value of **resource** under **metadata** in the **module.json5** file. This file is stored in the **Profile** folder.
Metadata resource configuration file example:
```json
{
"allowToBackupRestore": true,
"includes": [
"/data/storage/el2/base/files/users/*/*.json"
],
"excludes": [
"/data/storage/el2/base/files/users/*/hidden.json"
],
}
```
### Description of the Metadata Resource Configuration File
| Name | Type | Mandatory| Description |
| -------------------- | ---------- | ---- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| allowToBackupRestore | Boolean | Yes | Whether to allow backup and restoration. The default value is **false**. |
| includes | String array| No | Files and directories to be backed up in the application sandbox.<br>Each item in the array is a pattern string, which can contain shell-style wildcards such as *****, **?**, and **[**.<br>The pattern string that does not start with a slash (/) indicates a relative path relative to the root path.<br>If **includes** is configured, the backup and restoration framework uses the pattern strings configured. Otherwise, the backup and restoration framework uses the **includes** default value (see the following code segment).|
| excludes | String array| No | Exception items in **includes** that do not need to be backed up. The value is in the same format as **includes**.<br>If **excludes** is configured, the backup and restoration framework uses the pattern strings configured. Otherwise, the backup and restoration framework uses an empty array as the default value. |
**includes** default value:
```json
{
"includes": [
"data/storage/el2/database/",
"data/storage/el2/base/files/",
"data/storage/el2/base/preferences/",
"data/storage/el2/base/haps/*/database/",
"data/storage/el2/base/haps/*/base/files/",
"data/storage/el2/base/haps/*/base/preferences/",
]
}
```
# Application Data Backup and Restoration Overview
Application data, such as the configuration and service data, is generated when an application is used. To ensure that user data will not be lost due to operations, such as application updates and hopping, applications need to access data backup and restoration.
Before development, you need to understand the ExtensionAbility component. For details, see [ExtensionAbility Component Overview](../application-models/extensionability-overview.md).
BackupExtensionAbility is a class derived from ExtensionAbility in the stage model. It provides the capabilities of backing up and restoring application data. It is an extended component without the UI. It runs when a backup or restoration task starts and exits when the task is complete.
The implementation includes the following:
- [Backup and restoration of application access data](app-file-backup-extension.md): All applications can access data backup and restoration. After accessed, the application can modify the configuration file to customize the behavior of the backup and restoration framework, including whether to allow backup and restoration and specifying the data to be backed up.
Applications can perform backup and restoration configurations, but not trigger data backup and restoration.
- [Backup and restoration of application-triggered data](app-file-backup.md): Only system applications can trigger data backup and restoration. After data backup or restoration is triggered, the backup and restoration framework checks whether each application has accessed data backup and restoration. If yes, the backup and restore framework backs up or restores data based on the application's configuration file.
# Backing Up and Restoring Application-triggered Data (for System Applications Only)
The backup and restoration module provides a complete data backup and restoration solution for application data, user data, and system services on devices. You can implement data backup or restoration for applications by performing the following operations:
- [Obtaining the capability file](#obtaining-the-capability-file): Obtain the capability file of all applications of the system user. The capability file is indispensable for data backup and restoration.
- [Backing up application data](#backing-up-application-data): Select the application data to be backed up based on the application information provided by the capability file, and back up the data.
- [Restoring application data](#restoring-application-data): Select the application data to be restored based on the application information provided in the capability file and restore the data.
- [Installing the application during data restoration](#installing-the-application-during-data-restoration): Install the application if the application has not been installed. As an extended function of application data restoration, this function allows the application to be installed on the device before data restoration.
## How to Develop
For details about the APIs to be used, see [Backup and Restoration](../reference/apis/js-apis-file-backup.md).
Before using the APIs, you need to:
1. Apply for the ohos.permission.BACKUP permission. For details, see [Apply for permissions](../security/accesstoken-guidelines.md).
2. Import **@ohos.file.backup**.
```js
import backup from '@ohos.file.backup';
```
## Obtaining the Capability File
Obtain the application capability file of the current system user. This file is indispensable for application data backup and restoration.
This file contains the device type and version and basic application information, such as the application name, application data size, application version, whether to allow backup and restoration, and whether to install the application during restoration.
Use **backup.getLocalCapabilities()** to obtain the capability file.
```js
import fs from '@ohos.file.fs';
async function getLocalCapabilities() {
try {
let fileData = await backup.getLocalCapabilities();
console.info('getLocalCapabilities success');
let fpath = await globalThis.context.filesDir + '/localCapabilities.json';
fs.copyFileSync(fileData.fd, fpath);
fs.closeSync(fileData.fd);
} catch (err) {
console.error('getLocalCapabilities failed with err: ' + err);
}
}
```
**Capability file example**
| Name | Type| Mandatory| Description |
| -------------- | -------- | ---- | ---------------------- |
| bundleInfos | Array | Yes | Application information. |
| allToBackup | Boolean | Yes | Whether to allow backup and restoration. |
| extensionName | String | Yes | Extension name of the application. |
| name | String | Yes | Bundle name of the application. |
| needToInstall | Boolean | Yes | Whether to install the application during data restoration.|
| spaceOccupied | Number | Yes | Space occupied by the application data.|
| versionCode | Number | Yes | Application version number. |
| versionName | String | Yes | Application version name. |
| deviceType | String | Yes | Type of the device. |
| systemFullName | String | Yes | Device version. |
```json
{
"bundleInfos" :[{
"allToBackup" : true,
"extensionName" : "BackupExtensionAbility",
"name" : "com.example.hiworld",
"needToInstall" : false,
"spaceOccupied" : 0,
"versionCode" : 1000000,
"versionName" : "1.0.0"
}],
"deviceType" : "default",
"systemFullName" : "OpenHarmony-4.0.0.0"
}
```
## Backing Up Application Data
You need to select the application data to be backed up based on the application information provided by the capability file.
The Backup & Restore service packages the application data into a file. The file handle is returned by the [onFileReady](../reference/apis/js-apis-file-backup.md#onfileready) callback registered when the instance is created.
You can save the file to a local directory as required.
**Example**
```ts
import fs from '@ohos.file.fs';
// Create a SessionBackup instance for data backup.
let g_session;
function createSessionBackup() {
let sessionBackup = new backup.SessionBackup({
onFileReady: async (err, file) => {
if (err) {
console.info('onFileReady err: ' + err);
}
try {
let bundlePath = await globalThis.context.filesDir + '/' + file.bundleName;
if (!fs.accessSync(bundlePath)) {
fs.mkdirSync(bundlePath);
}
fs.copyFileSync(file.fd, bundlePath + `/${file.uri}`);
fs.closeSync(file.fd);
console.info('onFileReady success');
} catch (e) {
console.error('onFileReady failed with err: ' + e);
}
},
onBundleBegin: (err, bundleName) => {
if (err) {
console.info('onBundleBegin err: ' + err);
} else {
console.info('onBundleBegin bundleName: ' + bundleName);
}
},
onBundleEnd: (err, bundleName) => {
if (err) {
console.info('onBundleEnd err: ' + err);
} else {
console.info('onBundleEnd bundleName: ' + bundleName);
}
},
onAllBundlesEnd: (err) => {
if (err) {
console.info('onAllBundlesEnd err: ' + err);
} else {
console.info('onAllBundlesEnd');
}
},
onBackupServiceDied: () => {
console.info('onBackupServiceDied');
},
});
return sessionBackup;
}
async function sessionBackup ()
{
g_session = createSessionBackup();
// Select the application to be backed up based on the capability file obtained by backup.getLocalCapabilities().
// You can also back up data based on the application bundle name.
const backupApps = [
"com.example.hiworld",
]
await g_session.appendBundles(backupApps);
console.info('appendBundles success');
}
```
## Restoring Application Data
You can select the application data to be restored based on the application information provided by the capability file.
During the restoration, the Backup and Restore service returns the file handle of the application data to be restored in the [onFileReady](../reference/apis/js-apis-file-backup.md#onfileready) callback registered when the instance is created based on the [getFileHandle](../reference/apis/js-apis-file-backup.md#getfilehandle) called. Then, the data to be restored is written to the file handle based on the [uri](../reference/apis/js-apis-file-backup.md#filemeta) returned. After the data is written, use [publishFile()](../reference/apis/js-apis-file-backup.md#publishfile) to notify the service that the data write is complete.
When all the data of the application is ready, the service starts to restore the application data.
**Example**
```ts
import fs from '@ohos.file.fs';
// Create a SessionRestore instance for data restoration.
let g_session;
async function publishFile(file)
{
await g_session.publishFile({
bundleName: file.bundleName,
uri: file.uri
});
}
function createSessionRestore() {
let sessionRestore = new backup.SessionRestore({
onFileReady: (err, file) => {
if (err) {
console.info('onFileReady err: ' + err);
}
// Set bundlePath based on the actual situation.
let bundlePath;
if (!fs.accessSync(bundlePath)) {
console.info('onFileReady bundlePath err : ' + bundlePath);
}
fs.copyFileSync(bundlePath, file.fd);
fs.closeSync(file.fd);
// After the data is transferred, notify the server that the file is ready.
publishFile(file);
console.info('onFileReady success');
},
onBundleBegin: (err, bundleName) => {
if (err) {
console.error('onBundleBegin failed with err: ' + err);
}
console.info('onBundleBegin success');
},
onBundleEnd: (err, bundleName) => {
if (err) {
console.error('onBundleEnd failed with err: ' + err);
}
console.info('onBundleEnd success');
},
onAllBundlesEnd: (err) => {
if (err) {
console.error('onAllBundlesEnd failed with err: ' + err);
}
console.info('onAllBundlesEnd success');
},
onBackupServiceDied: () => {
console.info('service died');
}
});
return sessionRestore;
}
async function restore ()
{
g_session = createSessionRestore();
const backupApps = [
"com.example.hiworld",
]
// You can obtain the capability file based on actual situation. The following is an example only.
// You can also construct a capability file as required.
let fileData = await backup.getLocalCapabilities();
await g_session.appendBundles(fileData.fd, backupApps);
console.info('appendBundles success');
// After the application to be restored is added, call getFileHandle() to obtain the handle of the application file to be restored based on the application name.
// The number of application data files to be restored varies depending on the number of backup files. The following is only an example.
await g_session.getFileHandle({
bundleName: restoreApps[0],
uri: "manage.json"
});
await g_session.getFileHandle({
bundleName: restoreApps[0],
uri: "1.tar"
});
console.info('getFileHandle success');
}
```
## Installing the Application During Data Restoration
You can enable the application to be installed before application data restoration. To achieve this purpose, the value of **needToInstall** in **bundleInfos** in the [capability file](#obtaining-the-capability-file) must be **true**.
> **NOTE**
> - [Application data backup](#backing-up-application-data) does not support backup of the application installation package. Therefore, you need to obtain the application installation package.
> - To obtain the file handle of the application installation package, call [getFileHandle()](../reference/apis/js-apis-file-backup.md#getfilehandle) with **FileMeta.uri** set to **/data/storage/el2/restore/bundle.hap**. The file handle of the application installation package is returned through the **onFileReady()** callback registered when the instance is created. The returned **File.uri** is **data/storage/el2/restore/bundle.hap**.
**Example**
```ts
import fs from '@ohos.file.fs';
// Create a SessionRestore instance for data restoration.
let g_session;
async function publishFile(file)
{
await g_session.publishFile({
bundleName: file.bundleName,
uri: file.uri
});
}
function createSessionRestore() {
let sessionRestore = new backup.SessionRestore({
onFileReady: (err, file) => {
if (err) {
console.info('onFileReady err: ' + err);
}
let bundlePath;
if( file.uri == "/data/storage/el2/restore/bundle.hap" )
{
// Set the path of the application installation package based on actual situation.
} else {
// Set bundlePath based on the actual situation.
}
if (!fs.accessSync(bundlePath)) {
console.info('onFileReady bundlePath err : ' + bundlePath);
}
fs.copyFileSync(bundlePath, file.fd);
fs.closeSync(file.fd);
// After the data is transferred, notify the server that the file is ready.
publishFile(file);
console.info('onFileReady success');
},
onBundleBegin: (err, bundleName) => {
if (err) {
console.error('onBundleBegin failed with err: ' + err);
}
console.info('onBundleBegin success');
},
onBundleEnd: (err, bundleName) => {
if (err) {
console.error('onBundleEnd failed with err: ' + err);
}
console.info('onBundleEnd success');
},
onAllBundlesEnd: (err) => {
if (err) {
console.error('onAllBundlesEnd failed with err: ' + err);
}
console.info('onAllBundlesEnd success');
},
onBackupServiceDied: () => {
console.info('service died');
}
});
return sessionRestore;
}
async function restore ()
{
g_session = createSessionRestore();
const backupApps = [
"com.example.hiworld",
]
let fpath = await globalThis.context.filesDir + '/localCapabilities.json';
let file = fs.openSync(fpath, fileIO.OpenMode.CREATE | fileIO.OpenMode.READ_WRITE);
let content = "{\"bundleInfos\" :[{\"allToBackup\" : false,\"extensionName\" : \"\"," +
"\"name\" : \"cn.openharmony.inputmethodchoosedialog\",\"needToInstall\" : true,\"spaceOccupied\" : 0," +
"\"versionCode\" : 1000000,\"versionName\" : \"1.0.0\"}],\"deviceType\" : \"default\",\"systemFullName\" : \"OpenHarmony-4.0.6.2(Canary1)\"}";
fs.writeSync(file.fd, content);
fs.fsyncSync(file.fd);
await g_session.appendBundles(file.fd, backupApps);
console.info('appendBundles success');
// Obtain the file handle of the application to be installed.
await g_session.getFileHandle({
bundleName: restoreApps[0],
uri: "/data/storage/el2/restore/bundle.hap"
});
await g_session.getFileHandle({
bundleName: restoreApps[0],
uri: "manage.json"
});
await g_session.getFileHandle({
bundleName: restoreApps[0],
uri: "1.tar"
});
console.info('getFileHandle success');
}
```
**Capability file example**
```json
{
"bundleInfos" :[{
"allToBackup" : true,
"extensionName" : "BackupExtensionAbility",
"name" : "com.example.hiworld",
"needToInstall" : true,
"spaceOccupied" : 0,
"versionCode" : 1000000,
"versionName" : "1.0.0"
}],
"deviceType" : "default",
"systemFullName" : "OpenHarmony-4.0.0.0"
}
```
...@@ -10,7 +10,7 @@ For details about the APIs, see [ohos.file.statvfs](../reference/apis/js-apis-fi ...@@ -10,7 +10,7 @@ For details about the APIs, see [ohos.file.statvfs](../reference/apis/js-apis-fi
| Module| API| Description| | Module| API| Description|
| -------- | -------- | -------- | | -------- | -------- | -------- |
| \@ohos.file.storageStatistic | getCurrentBundleStats | Obtains the storage space of the current application, in bytes.| | \@ohos.file.storageStatistics | getCurrentBundleStats | Obtains the storage space of the current application, in bytes.|
| \@ohos.file.statvfs | getFreeSize | Obtains the free space of a file system, in bytes.| | \@ohos.file.statvfs | getFreeSize | Obtains the free space of a file system, in bytes.|
| \@ohos.file.statvfs | getTotalSize | Obtains the total space of a file system, in bytes.| | \@ohos.file.statvfs | getTotalSize | Obtains the total space of a file system, in bytes.|
......
# Developing a FileManager Application (Available Only for System Applications) # Developing a FileManager Application (for System Applications Only)
OpenHarmony is prebuilt with the **FileManager** application. You can also develop your own **FileManager** as required. OpenHarmony is prebuilt with the **FileManager** application. You can also develop your own **FileManager** as required.
......
# Managing External Storage Devices (Available Only for System Applications) # Managing External Storage Devices (for System Applications Only)
External storage devices are pluggable. OpenHarmony provides the functions of listening for the device insertion and removal events and mounting/unmounting an external storage device. External storage devices are pluggable. OpenHarmony provides the functions of listening for the device insertion and removal events and mounting/unmounting an external storage device.
...@@ -28,13 +28,13 @@ The following table describes the broadcast related parameters. ...@@ -28,13 +28,13 @@ The following table describes the broadcast related parameters.
**Table 1** Broadcast parameters **Table 1** Broadcast parameters
| Broadcast| Parameter| | Broadcast| Parameter|
| -------- | -------- | | -------- | -------- |
| usual.event.data.VOLUME_REMOVED | **id**: ID of the volume.<br>**diskId**: ID of the disk to which the volume belongs.| | usual.event.data.VOLUME_REMOVED | **id**: ID of the volume.<br>**diskId**: ID of the disk to which the volume belongs.|
| usual.event.data.VOLUME_UNMOUNTED | **id**: ID of the volume.<br>**diskId**: ID of the disk to which the volume belongs.<br>**volumeState**: state of the volume.| | usual.event.data.VOLUME_UNMOUNTED | **id**: ID of the volume.<br>**diskId**: ID of the disk to which the volume belongs.<br>**volumeState**: state of the volume.|
| usual.event.data.VOLUME_MOUNTED | **id**: ID of the volume.<br>**diskId**: ID of the disk to which the volume belongs.<br>**volumeState**: state of the volume.<br>**fsUuid**: universally unique identifier (UUID) of the volume.<br>**path**: path where the volume is mounted.| | usual.event.data.VOLUME_MOUNTED | **id**: ID of the volume.<br>**diskId**: ID of the disk to which the volume belongs.<br>**volumeState**: state of the volume.<br>**fsUuid**: universally unique identifier (UUID) of the volume.<br>**path**: path where the volume is mounted.|
| usual.event.data.VOLUME_BAD_REMOVAL | **id**: ID of the volume.<br>**diskId**: ID of the disk to which the volume belongs.| | usual.event.data.VOLUME_BAD_REMOVAL | **id**: ID of the volume.<br>**diskId**: ID of the disk to which the volume belongs.|
| usual.event.data.VOLUME_EJECT | **id**: ID of the volume.<br>**diskId**: ID of the disk to which the volume belongs.<br>**volumeState**: state of the volume.| | usual.event.data.VOLUME_EJECT | **id**: ID of the volume.<br>**diskId**: ID of the disk to which the volume belongs.<br>**volumeState**: state of the volume.|
## How to Develop ## How to Develop
......
...@@ -7,10 +7,11 @@ The operations for saving images, audio or video clips, and documents are simila ...@@ -7,10 +7,11 @@ The operations for saving images, audio or video clips, and documents are simila
## Saving Images or Video Files ## Saving Images or Video Files
1. Import the **FilePicker** module. 1. Import the **picker** module and **fs** module.
```ts ```ts
import picker from '@ohos.file.picker'; import picker from '@ohos.file.picker';
import fs from '@ohos.file.fs';
``` ```
2. Create a **photoSaveOptions** instance. 2. Create a **photoSaveOptions** instance.
...@@ -20,27 +21,43 @@ The operations for saving images, audio or video clips, and documents are simila ...@@ -20,27 +21,43 @@ The operations for saving images, audio or video clips, and documents are simila
photoSaveOptions.newFileNames = ["PhotoViewPicker01.jpg"]; // (Optional) Set the names of the files to save. photoSaveOptions.newFileNames = ["PhotoViewPicker01.jpg"]; // (Optional) Set the names of the files to save.
``` ```
3. Create a **photoViewPicker** instance and call [save()](../reference/apis/js-apis-file-picker.md#save) to open the **FilePicker** page to save the files. 3. Create a **photoViewPicker** instance and call [save()](../reference/apis/js-apis-file-picker.md#save) to open the **FilePicker** page to save the files. After the user selects the target folder, the file saving operation is complete. After the files are saved successfully, the URIs of the files saved are returned.
After the user selects the target folder, the file saving operation is complete. After the files are saved successfully, the URIs of the files saved are returned.
<br>The permission on the URIs returned by **save()** is read/write. Further file operations can be performed based on the URIs in the result set. Note that the URI cannot be directly used in the **picker** callback to open a file. You need to define a global variable to save the URI and use a button to trigger file opening.
```ts ```ts
let URI = null;
const photoViewPicker = new picker.PhotoViewPicker(); const photoViewPicker = new picker.PhotoViewPicker();
photoViewPicker.save(photoSaveOptions) photoViewPicker.save(photoSaveOptions).then((photoSaveResult) => {
.then(async (photoSaveResult) => { URI = photoSaveResult[0];
let uri = photoSaveResult[0]; console.info('photoViewPicker.save to file succeed and URI is:' + URI);
// Perform operations on the files based on the file URIs obtained. }).catch((err) => {
}) console.error(`Invoke photoViewPicker.save failed, code is ${err.code}, message is ${err.message}`);
.catch((err) => { })
console.error(`Invoke documentPicker.select failed, code is ${err.code}, message is ${err.message}`); ```
})
4. Use a button to trigger invocation of other functions. Use [fs.openSync()](../reference/apis/js-apis-file-fs.md#fsopensync) to open the file based on the URI and obtain the FD. Note that the **mode** parameter of **fs.openSync()** must be **fs.OpenMode.READ_WRITE**.
```ts
let file = fs.openSync(URI, fs.OpenMode.READ_WRITE);
console.info('file fd: ' + file.fd);
```
5. Use [fs.writeSync()](../reference/apis/js-apis-file-fs.md#writesync) to edit the file based on the FD, and then close the FD.
```ts
let writeLen = fs.writeSync(file.fd, 'hello, world');
console.info('write data to file succeed and size is:' + writeLen);
fs.closeSync(file);
``` ```
## Saving Documents ## Saving Documents
1. Import the **FilePicker** module. 1. Import the **picker** module and **fs** module.
```ts ```ts
import picker from '@ohos.file.picker'; import picker from '@ohos.file.picker';
import fs from '@ohos.file.fs';
``` ```
2. Create a **documentSaveOptions** instance. 2. Create a **documentSaveOptions** instance.
...@@ -50,31 +67,43 @@ The operations for saving images, audio or video clips, and documents are simila ...@@ -50,31 +67,43 @@ The operations for saving images, audio or video clips, and documents are simila
documentSaveOptions.newFileNames = ["DocumentViewPicker01.txt"]; // (Optional) Set the names of the documents to save. documentSaveOptions.newFileNames = ["DocumentViewPicker01.txt"]; // (Optional) Set the names of the documents to save.
``` ```
3. Create a **documentViewPicker** instance, and call [save()](../reference/apis/js-apis-file-picker.md#save-3) to open the **FilePicker** page to save the documents. 3. Create a **documentViewPicker** instance, and call [save()](../reference/apis/js-apis-file-picker.md#save-3) to open the **FilePicker** page to save the documents. After the user selects the target folder, the file saving operation is complete. After the files are saved successfully, the URIs of the files saved are returned.
After the user selects the target folder, the file saving operation is complete. After the files are saved successfully, the URIs of the files saved are returned.
The permission on the URIs returned by **save()** is read/write. Further file operations can be performed based on the URIs in the result set. Note that the URI cannot be directly used in the **picker** callback to open a file. You need to define a global variable to save the URI and use a button to trigger file opening.
> **NOTE**
>
> Currently, **DocumentSelectOptions** is not configurable. By default, all types of user files are selected.
```ts ```ts
let URI = null;
const documentViewPicker = new picker.DocumentViewPicker(); // Create a documentViewPicker instance. const documentViewPicker = new picker.DocumentViewPicker(); // Create a documentViewPicker instance.
documentViewPicker.save(documentSaveOptions) documentViewPicker.save(documentSaveOptions).then((documentSaveResult) => {
.then(async (documentSaveResult) => { URI = documentSaveResult[0];
let uri = documentSaveResult[0]; console.info('documentViewPicker.save to file succeed and URI is:' + URI);
// For example, write data to the documents based on the obtained URIs. }).catch((err) => {
}) console.error(`Invoke documentViewPicker.save failed, code is ${err.code}, message is ${err.message}`);
.catch((err) => { })
console.error(`Invoke documentPicker.save failed, code is ${err.code}, message is ${err.message}`); ```
})
4. Use a button to trigger invocation of other functions. Use [fs.openSync()](../reference/apis/js-apis-file-fs.md#fsopensync) to open the file based on the URI and obtain the FD. Note that the **mode** parameter of **fs.openSync()** must be **fs.OpenMode.READ_WRITE**.
```ts
let file = fs.openSync(URI, fs.OpenMode.READ_WRITE);
console.info('file fd: ' + file.fd);
```
5. Use [fs.writeSync()](../reference/apis/js-apis-file-fs.md#writesync) to edit the file based on the FD, and then close the FD.
```ts
let writeLen = fs.writeSync(file.fd, 'hello, world');
console.info('write data to file succeed and size is:' + writeLen);
fs.closeSync(file);
``` ```
## Saving Audio Files ## Saving Audio Files
1. Import the **FilePicker** module. 1. Import the **picker** module and **fs** module.
```ts ```ts
import picker from '@ohos.file.picker'; import picker from '@ohos.file.picker';
import fs from '@ohos.file.fs';
``` ```
2. Create an **audioSaveOptions** instance. 2. Create an **audioSaveOptions** instance.
...@@ -84,20 +113,33 @@ The operations for saving images, audio or video clips, and documents are simila ...@@ -84,20 +113,33 @@ The operations for saving images, audio or video clips, and documents are simila
audioSaveOptions.newFileNames = ['AudioViewPicker01.mp3']; // (Optional) Set the names of the files to save. audioSaveOptions.newFileNames = ['AudioViewPicker01.mp3']; // (Optional) Set the names of the files to save.
``` ```
3. Create an **audioViewPicker** instance, and call [save()](../reference/apis/js-apis-file-picker.md#save-6) to open the **FilePicker** page to save the files. 3. Create an **audioViewPicker** instance, and call [save()](../reference/apis/js-apis-file-picker.md#save-6) to open the **FilePicker** page to save the files. After the user selects the target folder, the file saving operation is complete. After the files are saved successfully, the URIs of the files saved are returned.
After the user selects the target folder, the file saving operation is complete. After the files are saved successfully, the URIs of the files saved are returned.
> **NOTE** The permission on the URIs returned by **save()** is read/write. Further file operations can be performed based on the URIs in the result set. Note that the URI cannot be directly used in the **picker** callback to open a file. You need to define a global variable to save the URI and use a button to trigger file opening.
>
> Currently, **AudioSelectOptions** is not configurable. By default, all types of user files are selected.
```ts ```ts
let URI = null;
const audioViewPicker = new picker.AudioViewPicker(); const audioViewPicker = new picker.AudioViewPicker();
audioViewPicker.save(audioSaveOptions) audioViewPicker.save(audioSaveOptions).then((audioSelectResult) => {
.then((audioSelectResult) => { URI = audioSelectResult[0];
let uri = audioSelectResult[0]; console.info('audioViewPicker.save to file succeed and URI is:' + URI);
// Perform operations on the audio files based on the file URIs. }).catch((err) => {
}) console.error(`Invoke audioViewPicker.save failed, code is ${err.code}, message is ${err.message}`);
.catch((err) => { })
console.error(`Invoke audioPicker.select failed, code is ${err.code}, message is ${err.message}`); ```
})
4. Use a button to trigger invocation of other functions. Use [fs.openSync()](../reference/apis/js-apis-file-fs.md#fsopensync) to open the file based on the URI and obtain the FD. Note that the **mode** parameter of **fs.openSync()** must be **fs.OpenMode.READ_WRITE**.
```ts
let file = fs.openSync(URI, fs.OpenMode.READ_WRITE);
console.info('file fd: ' + file.fd);
```
5. Use [fs.writeSync](../reference/apis/js-apis-file-fs.md#writesync) to edit the file based on the FD, and then close the FD.
```ts
let writeLen = fs.writeSync(file.fd, 'hello, world');
console.info('write data to file succeed and size is:' + writeLen);
fs.closeSync(file);
``` ```
# Selecting User Files # Selecting User Files
If your application needs to support share and saving of user files (such as images and videos) by users, you can use the [FilePicker](../reference/apis/js-apis-file-picker.md) prebuilt in OpenHarmony to implement selecting and saving of user files. If your application needs to support share and saving of user files (such as images and videos), you can use OpenHarmony [FilePicker](../reference/apis/js-apis-file-picker.md) to implement selection and saving of user files.
The **FilePicker** provides the following interfaces by file type: The **FilePicker** provides the following interfaces by file type:
...@@ -12,10 +12,11 @@ The **FilePicker** provides the following interfaces by file type: ...@@ -12,10 +12,11 @@ The **FilePicker** provides the following interfaces by file type:
## Selecting Images or Video Files ## Selecting Images or Video Files
1. Import the **FilePicker** module. 1. Import the **picker** module and **fs** module.
```ts ```ts
import picker from '@ohos.file.picker'; import picker from '@ohos.file.picker';
import fs from '@ohos.file.fs';
``` ```
2. Create a **photoSelectOptions** instance. 2. Create a **photoSelectOptions** instance.
...@@ -32,41 +33,44 @@ The **FilePicker** provides the following interfaces by file type: ...@@ -32,41 +33,44 @@ The **FilePicker** provides the following interfaces by file type:
photoSelectOptions.maxSelectNumber = 5; // Set the maximum number of images to select. photoSelectOptions.maxSelectNumber = 5; // Set the maximum number of images to select.
``` ```
4. Create a **photoPicker** instance and call [select()](../reference/apis/js-apis-file-picker.md#select) to open the **FilePicker** page for the user to select files. 4. Create a **photoPicker** instance and call [select()](../reference/apis/js-apis-file-picker.md#select) to open the **FilePicker** page for the user to select files. After the files are selected, [PhotoSelectResult](../reference/apis/js-apis-file-picker.md#photoselectresult) is returned.
Use [PhotoSelectResult](../reference/apis/js-apis-file-picker.md#photoselectresult) to return a result set. Further operations on the selected files can be performed based on the file URIs in the result set. <br>The permission on the URIs returned by **select()** is read-only. Further file operations can be performed based on the URIs in the **PhotoSelectResult**. Note that the URI cannot be directly used in the **picker** callback to open a file. You need to define a global variable to save the URI and use a button to trigger file opening.
```ts ```ts
let uri = null; let URI = null;
const photoPicker = new picker.PhotoViewPicker(); const photoViewPicker = new picker.PhotoViewPicker();
photoPicker.select(photoSelectOptions).then((photoSelectResult) => { photoViewPicker.select(photoSelectOptions).then((photoSelectResult) => {
uri = photoSelectResult.photoUris[0]; URI = photoSelectResult.photoUris[0];
console.info('photoViewPicker.select to file succeed and URI is:' + URI);
}).catch((err) => { }).catch((err) => {
console.error(`Invoke photoPicker.select failed, code is ${err.code}, message is ${err.message}`); console.error(`Invoke photoViewPicker.select failed, code is ${err.code}, message is ${err.message}`);
}) })
``` ```
5. After the GUI is returned from FilePicker, use [**fs.openSync**](../reference/apis/js-apis-file-fs.md#fsopensync) to open the file based on the URI and obtain the FD. 5. Use a button to trigger invocation of other functions. Use [fs.openSync()](../reference/apis/js-apis-file-fs.md#fsopensync) to open the file based on the URI and obtain the FD. Note that the **mode** parameter of **fs.openSync()** must be **fs.OpenMode.READ_ONLY**.
```ts ```ts
let file = fs.openSync(uri, fs.OpenMode.READ_WRITE); let file = fs.openSync(URI, fs.OpenMode.READ_ONLY);
console.info('file fd: ' + file.fd); console.info('file fd: ' + file.fd);
``` ```
6. Use [fs.writeSync](../reference/apis/js-apis-file-fs.md#writesync) to write data to the file based on the FD, and then close the FD. 6. Use [fs.readSync()](../reference/apis/js-apis-file-fs.md#readsync) to read the file data based on the FD. After the data is read, close the FD.
```ts ```ts
let writeLen = fs.writeSync(file.fd, 'hello, world'); let buffer = new ArrayBuffer(4096);
console.info('write data to file succeed and size is:' + writeLen); let readLen = fs.readSync(file.fd, buffer);
console.info('readSync data to file succeed and buffer size is:' + readLen);
fs.closeSync(file); fs.closeSync(file);
``` ```
## Selecting Documents ## Selecting Documents
1. Import the **FilePicker** module. 1. Import the **picker** module and **fs** module.
```ts ```ts
import picker from '@ohos.file.picker'; import picker from '@ohos.file.picker';
import fs from '@ohos.file.fs';
``` ```
2. Create a **documentSelectOptions** instance. 2. Create a **documentSelectOptions** instance.
...@@ -75,23 +79,24 @@ The **FilePicker** provides the following interfaces by file type: ...@@ -75,23 +79,24 @@ The **FilePicker** provides the following interfaces by file type:
const documentSelectOptions = new picker.DocumentSelectOptions(); const documentSelectOptions = new picker.DocumentSelectOptions();
``` ```
3. Create a **documentViewPicker** instance, and call [**select()**](../reference/apis/js-apis-file-picker.md#select-3) to open the **FilePicker** page for the user to select documents. 3. Create a **documentViewPicker** instance, and call [**select()**](../reference/apis/js-apis-file-picker.md#select-3) to open the **FilePicker** page for the user to select documents. After the documents are selected, a result set containing the file URIs is returned.
After the documents are selected successfully, a result set containing the file URIs is returned. Further operations can be performed on the documents based on the file URIs. <br>The permission on the URIs returned by **select()** is read-only. Further file operations can be performed based on the URIs in the result set. Note that the URI cannot be directly used in the **picker** callback to open a file. You need to define a global variable to save the URI and use a button to trigger file opening.
For example, you can use [file management APIs](../reference/apis/js-apis-file-fs.md) to obtain file attribute information, such as the file size, access time, and last modification time, based on the URI. If you need to obtain the file name, use [startAbilityForResult](../../application-dev/application-models/uiability-intra-device-interaction.md). <br>For example, you can use [file management APIs](../reference/apis/js-apis-file-fs.md) to obtain file attribute information, such as the file size, access time, and last modification time, based on the URI. If you need to obtain the file name, use [startAbilityForResult](../../application-dev/application-models/uiability-intra-device-interaction.md).
> **NOTE** > **NOTE**
> >
> Currently, **DocumentSelectOptions** is not configurable. By default, all types of user files are selected. > Currently, **DocumentSelectOptions** is not configurable. By default, all types of user files are selected.
```ts ```ts
let uri = null; let URI = null;
const documentViewPicker = new picker.DocumentViewPicker(); // Create a documentViewPicker instance. const documentViewPicker = new picker.DocumentViewPicker(); // Create a documentViewPicker instance.
documentViewPicker.select(documentSelectOptions).then((documentSelectResult) => { documentViewPicker.select(documentSelectOptions).then((documentSelectResult) => {
uri = documentSelectResult[0]; URI = documentSelectResult[0];
console.info('documentViewPicker.select to file succeed and URI is:' + URI);
}).catch((err) => { }).catch((err) => {
console.error(`Invoke documentPicker.select failed, code is ${err.code}, message is ${err.message}`); console.error(`Invoke documentViewPicker.select failed, code is ${err.code}, message is ${err.message}`);
}) })
``` ```
...@@ -109,7 +114,7 @@ The **FilePicker** provides the following interfaces by file type: ...@@ -109,7 +114,7 @@ The **FilePicker** provides the following interfaces by file type:
try { try {
let result = await context.startAbilityForResult(config, {windowMode: 1}); let result = await context.startAbilityForResult(config, {windowMode: 1});
if (result.resultCode !== 0) { if (result.resultCode !== 0) {
console.error(`DocumentPicker.select failed, code is ${result.resultCode}, message is ${result.want.parameters.message}`); console.error(`documentViewPicker.select failed, code is ${result.resultCode}, message is ${result.want.parameters.message}`);
return; return;
} }
// Obtain the URI of the document. // Obtain the URI of the document.
...@@ -117,34 +122,34 @@ The **FilePicker** provides the following interfaces by file type: ...@@ -117,34 +122,34 @@ The **FilePicker** provides the following interfaces by file type:
// Obtain the name of the document. // Obtain the name of the document.
let file_name_list = result.want.parameters.file_name_list; let file_name_list = result.want.parameters.file_name_list;
} catch (err) { } catch (err) {
console.error(`Invoke documentPicker.select failed, code is ${err.code}, message is ${err.message}`); console.error(`Invoke documentViewPicker.select failed, code is ${err.code}, message is ${err.message}`);
} }
``` ```
4. After the GUI is returned from FilePicker, use [**fs.openSync**](../reference/apis/js-apis-file-fs.md#fsopensync) to open the file based on the URI and obtain the FD. 4. Use a button to trigger invocation of other functions. Use [fs.openSync()](../reference/apis/js-apis-file-fs.md#fsopensync) to open the file based on the URI and obtain the FD. Note that the **mode** parameter of **fs.openSync()** must be **fs.OpenMode.READ_ONLY**.
```ts ```ts
let file = fs.openSync(uri, fs.OpenMode.READ_WRITE); let file = fs.openSync(URI, fs.OpenMode.READ_ONLY);
console.info('file fd: ' + file.fd); console.info('file fd: ' + file.fd);
``` ```
5. Use [fs.readSync](../reference/apis/js-apis-file-fs.md#readsync) to read data from the file based on the FD, and then close the FD. 5. Use [fs.readSync()](../reference/apis/js-apis-file-fs.md#readsync) to read the file data based on the FD. After the data is read, close the FD.
```ts ```ts
let file = fs.openSync(uri, fs.OpenMode.READ_WRITE); let buffer = new ArrayBuffer(4096);
let buf = new ArrayBuffer(4096); let readLen = fs.readSync(file.fd, buffer);
let num = fs.readSync(file.fd, buf); console.info('readSync data to file succeed and buffer size is:' + readLen);
console.info('read data to file succeed and size is:' + num);
fs.closeSync(file); fs.closeSync(file);
``` ```
## Selecting an Audio File ## Selecting an Audio File
1. Import the **FilePicker** module. 1. Import the **picker** module and **fs** module.
```ts ```ts
import picker from '@ohos.file.picker'; import picker from '@ohos.file.picker';
import fs from '@ohos.file.fs';
``` ```
2. Create an **audioSelectOptions** instance. 2. Create an **audioSelectOptions** instance.
...@@ -153,37 +158,39 @@ The **FilePicker** provides the following interfaces by file type: ...@@ -153,37 +158,39 @@ The **FilePicker** provides the following interfaces by file type:
const audioSelectOptions = new picker.AudioSelectOptions(); const audioSelectOptions = new picker.AudioSelectOptions();
``` ```
3. Create an **audioViewPicker** instance, and call [**select()**](../reference/apis/js-apis-file-picker.md#select-6) to open the **FilePicker** page for the user to select audio files. 3. Create an **audioViewPicker** instance, and call [**select()**](../reference/apis/js-apis-file-picker.md#select-6) to open the **FilePicker** page for the user to select audio files. After the files are selected, a result set containing the URIs of the audio files selected is returned.
After the files are selected successfully, a result set containing the URIs of the audio files selected is returned. Further operations can be performed on the documents based on the file URIs. <br>The permission on the URIs returned by **select()** is read-only. Further file operations can be performed based on the URIs in the result set. Note that the URI cannot be directly used in the **picker** callback to open a file. You need to define a global variable to save the URI and use a button to trigger file opening.
For example, use the [file management interface](../reference/apis/js-apis-file-fs.md) to obtain the file handle (FD) of the audio clip based on the URI, and then develop the audio playback function based on the media service. For details, see [Audio Playback Development](../media/audio-playback-overview.md). <br>For example, use the [file management interface](../reference/apis/js-apis-file-fs.md) to obtain the file handle (FD) of the audio clip based on the URI, and then develop the audio playback function based on the media service. For details, see [Audio Playback Development](../media/audio-playback-overview.md).
> **NOTE** > **NOTE**
> >
> Currently, **AudioSelectOptions** is not configurable. By default, all types of user files are selected. > Currently, **AudioSelectOptions** is not configurable. By default, all types of user files are selected.
```ts ```ts
let uri = null; let URI = null;
const audioViewPicker = new picker.AudioViewPicker(); const audioViewPicker = new picker.AudioViewPicker();
audioViewPicker.select(audioSelectOptions).then(audioSelectResult => { audioViewPicker.select(audioSelectOptions).then(audioSelectResult => {
uri = audioSelectOptions[0]; URI = audioSelectOptions[0];
console.info('audioViewPicker.select to file succeed and URI is:' + URI);
}).catch((err) => { }).catch((err) => {
console.error(`Invoke audioPicker.select failed, code is ${err.code}, message is ${err.message}`); console.error(`Invoke audioViewPicker.select failed, code is ${err.code}, message is ${err.message}`);
}) })
``` ```
4. After the GUI is returned from FilePicker, use [**fs.openSync**](../reference/apis/js-apis-file-fs.md#fsopensync) to open the file based on the URI and obtain the FD. 4. Use a button to trigger invocation of other functions. Use [fs.openSync()](../reference/apis/js-apis-file-fs.md#fsopensync) to open the file based on the URI and obtain the FD. Note that the **mode** parameter of **fs.openSync()** must be **fs.OpenMode.READ_ONLY**.
```ts ```ts
let file = fs.openSync(uri, fs.OpenMode.READ_WRITE); let file = fs.openSync(URI, fs.OpenMode.READ_ONLY);
console.info('file fd: ' + file.fd); console.info('file fd: ' + file.fd);
``` ```
5. Use [fs.writeSync](../reference/apis/js-apis-file-fs.md#writesync) to write data to the file based on the FD, and then close the FD. 5. Use [fs.readSync()](../reference/apis/js-apis-file-fs.md#readsync) to read the file data based on the FD. After the data is read, close the FD.
```ts ```ts
let writeLen = fs.writeSync(file.fd, 'hello, world'); let buffer = new ArrayBuffer(4096);
console.info('write data to file succeed and size is:' + writeLen); let readLen = fs.readSync(file.fd, buffer);
console.info('readSync data to file succeed and buffer size is:' + readLen);
fs.closeSync(file); fs.closeSync(file);
``` ```
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册