未验证 提交 b16a45dd 编写于 作者: O openharmony_ci 提交者: Gitee

!22994 翻译完成:master EN 更新内容合入到monthly分支

Merge pull request !22994 from wusongqing/monthly_20230815
...@@ -62,7 +62,7 @@ sequenceable a.b..C.D ...@@ -62,7 +62,7 @@ sequenceable a.b..C.D
The preceding statement is parsed into the following code in the C++ header file: The preceding statement is parsed into the following code in the C++ header file:
```cpp ```cpp
#include "a/b/d.h" #include "a/b/d.h"
using C::D; using C::D;
``` ```
...@@ -347,11 +347,10 @@ export default { ...@@ -347,11 +347,10 @@ export default {
#### Calling Methods from the Client for IPC #### Calling Methods from the Client for IPC
When the client calls **connectAbility()** to connect to a Service ability, the **onConnect** callback in **onAbilityConnectDone** of the client receives the **IRemoteObject** instance returned by the **onConnect()** method of the Service ability. The client and Service ability are in different applications. Therefore, the directory of the client application must contain a copy of the .idl file (the SDK automatically generates the proxy class). The **onConnect** callback then uses the **IRemoteObject** instance to create the **testProxy** instance of the **IdlTestServiceProxy** class and calls the related IPC method. The sample code is as follows: When the client calls **connectServiceExtensionAbility()** to connect to a Service ability, the **onConnect** callback in **onAbilityConnectDone** of the client receives the **IRemoteObject** instance returned by the **onConnect()** method of the Service ability. The client and Service ability are in different applications. Therefore, the directory of the client application must contain a copy of the .idl file (the SDK automatically generates the proxy class). The **onConnect** callback then uses the **IRemoteObject** instance to create the **testProxy** instance of the **IdlTestServiceProxy** class and calls the related IPC method. The sample code is as follows:
```ts ```ts
import IdlTestServiceProxy from './idl_test_service_proxy' import IdlTestServiceProxy from './idl_test_service_proxy'
import featureAbility from '@ohos.ability.featureAbility';
function callbackTestIntTransaction(result: number, ret: number): void { function callbackTestIntTransaction(result: number, ret: number): void {
if (result == 0 && ret == 124) { if (result == 0 && ret == 124) {
...@@ -396,13 +395,13 @@ var onAbilityConnectDone = { ...@@ -396,13 +395,13 @@ var onAbilityConnectDone = {
} }
}; };
function connectAbility: void { function connectAbility(): void {
let want = { let want = {
bundleName: 'com.example.myapplicationidl', bundleName: 'com.example.myapplicationidl',
abilityName: 'com.example.myapplicationidl.ServiceAbility' abilityName: 'com.example.myapplicationidl.ServiceAbility'
}; };
let connectionId = -1; let connectionId = -1;
connectionId = featureAbility.connectAbility(want, onAbilityConnectDone); connectionId = this.context.connectServiceExtensionAbility(want, onAbilityConnectDone);
} }
......
...@@ -61,7 +61,7 @@ ...@@ -61,7 +61,7 @@
- [Component Startup Rules (Stage Model)](component-startup-rules.md) - [Component Startup Rules (Stage Model)](component-startup-rules.md)
- Inter-Device Application Component Interaction (Continuation) - Inter-Device Application Component Interaction (Continuation)
- [Continuation Overview](inter-device-interaction-hop-overview.md) - [Continuation Overview](inter-device-interaction-hop-overview.md)
- [Cross-Device Migration (for System Applications Only)](hop-cross-device-migration.md) - [Cross-Device Migration](hop-cross-device-migration.md)
- [Multi-device Collaboration (for System Applications Only)](hop-multi-device-collaboration.md) - [Multi-device Collaboration (for System Applications Only)](hop-multi-device-collaboration.md)
- [Subscribing to System Environment Variable Changes](subscribe-system-environment-variable-changes.md) - [Subscribing to System Environment Variable Changes](subscribe-system-environment-variable-changes.md)
- Process Model - Process Model
......
...@@ -118,7 +118,12 @@ After developing the custom logic for an accessibility extension service, you mu ...@@ -118,7 +118,12 @@ After developing the custom logic for an accessibility extension service, you mu
``` ```
## Enabling or Disabling a Custom Accessibility Extension Service ## Enabling or Disabling a Custom Accessibility Extension Service
To enable or disable an accessibility extension service, run the following command: You can enable or disable a custom accessibility extension service through the command line interface or the device settings.
**Method 1**: through the command line interface
Run the **hdc shell** command, then the following system command:
- To enable the service: **accessibility enable -a AccessibilityExtAbility -b com.example.demo -c rg** - To enable the service: **accessibility enable -a AccessibilityExtAbility -b com.example.demo -c rg**
- To disable the service: **accessibility disable -a AccessibilityExtAbility -b com.example.demo** - To disable the service: **accessibility disable -a AccessibilityExtAbility -b com.example.demo**
...@@ -126,3 +131,9 @@ In the preceding commands, **AccessibilityExtAbility** indicates the name of the ...@@ -126,3 +131,9 @@ In the preceding commands, **AccessibilityExtAbility** indicates the name of the
If the service is enabled or disabled successfully, the message "enable ability successfully" or "disable ability successfully" is displayed. If the service is enabled or disabled successfully, the message "enable ability successfully" or "disable ability successfully" is displayed.
**Method 2**: through the device settings
- From the device settings screen, access the list of installed extended services under accessibility.
If an extended service is not installed, it is grayed out, and "No service" is displayed.
- Select the target extended service, and toggle on or off the switch to enable or disable it.
- If you opt to enable a service, a security reminder is displayed. Wait until the countdown ends and then select the check box indicating that you are aware of and willing to assume the listed risks.
...@@ -54,7 +54,7 @@ Widget-related configuration includes **FormExtensionAbility** configuration and ...@@ -54,7 +54,7 @@ Widget-related configuration includes **FormExtensionAbility** configuration and
| formVisibleNotify | Whether the widget is allowed to use the widget visibility notification.| String| Yes (initial value: left empty)| | formVisibleNotify | Whether the widget is allowed to use the widget visibility notification.| String| Yes (initial value: left empty)|
| metadata | Metadata of the widget. This field contains the array of the **customizeData** field.| Object| Yes (initial value: left empty)| | metadata | Metadata of the widget. This field contains the array of the **customizeData** field.| Object| Yes (initial value: left empty)|
| dataProxyEnabled | Whether the widget supports the [update-through-proxy](./arkts-ui-widget-update-by-proxy.md) feature.<br>- **true**: The widget supports the update-through-proxy feature.<br>- **false**: The widget does not support the update-through-proxy feature.<br>If this tag is set to **true**, the settings for the scheduled update time will still take effect, but the settings for the update interval and next update time will not.| Boolean| Yes (initial value: **false**)| | dataProxyEnabled | Whether the widget supports the [update-through-proxy](./arkts-ui-widget-update-by-proxy.md) feature.<br>- **true**: The widget supports the update-through-proxy feature.<br>- **false**: The widget does not support the update-through-proxy feature.<br>If this tag is set to **true**, the settings for the scheduled update time will still take effect, but the settings for the update interval and next update time will not.| Boolean| Yes (initial value: **false**)|
| isDynamic | Whether the widget is a dynamic widget. This tag only applies to ArkTS widgets.<br>- **true**: The widget is a dynamic widget.<br>- **false**: The widget is a static widget. In this case, the widget is displayed as a static image after being added.| Boolean| Yes (initial value: **true**)| | isDynamic | Whether the widget is a dynamic widget. This tag applies only to ArkTS widgets.<br>- **true**: The widget is a dynamic widget.<br>- **false**: The widget is a static widget. In this case, the widget is displayed as a static image after being added.| Boolean| Yes (initial value: **true**)|
**Table 2** Internal structure of the window object **Table 2** Internal structure of the window object
......
...@@ -26,7 +26,7 @@ In view of this, OpenHarmony formulates a set of component startup rules, as fol ...@@ -26,7 +26,7 @@ In view of this, OpenHarmony formulates a set of component startup rules, as fol
- If the **exported** field of the target component is **false**, verify the **ohos.permission.START_INVISIBLE_ABILITY** permission. - If the **exported** field of the target component is **false**, verify the **ohos.permission.START_INVISIBLE_ABILITY** permission.
- For details, see [Component exported Configuration](../quick-start/module-configuration-file.md#abilities). - For details, see [Component exported Configuration](../quick-start/module-configuration-file.md#abilities).
- **Before starting a component of a background application, verify the BACKGROUND permission.** - **Before starting a UIAbility component of a background application, verify the BACKGROUND permission.**
- An application is considered as a foreground application only when the application process gains focus or its UIAbility component is running in the foreground. - An application is considered as a foreground application only when the application process gains focus or its UIAbility component is running in the foreground.
- Verify the **ohos.permission.START_ABILITIES_FROM_BACKGROUND** permission. - Verify the **ohos.permission.START_ABILITIES_FROM_BACKGROUND** permission.
...@@ -45,7 +45,9 @@ In view of this, OpenHarmony formulates a set of component startup rules, as fol ...@@ -45,7 +45,9 @@ In view of this, OpenHarmony formulates a set of component startup rules, as fol
The rules for starting components on the same device vary in the following scenarios: The rules for starting components on the same device vary in the following scenarios:
- Starting or connecting to the UIAbility, ServiceExtensionAbility, and DataShareExtensionAbility components - Starting the UIAbility component
- Starting the ServiceExtensionAbility and DataShareExtensionAbility components
- Using **startAbilityByCall()** to start the UIAbility component - Using **startAbilityByCall()** to start the UIAbility component
...@@ -56,9 +58,10 @@ In view of this, OpenHarmony formulates a set of component startup rules, as fol ...@@ -56,9 +58,10 @@ In view of this, OpenHarmony formulates a set of component startup rules, as fol
The rules for starting components on a different device vary in the following scenarios: The rules for starting components on a different device vary in the following scenarios:
- Starting or connecting to the UIAbility, ServiceExtensionAbility, and DataShareExtensionAbility components - Starting the UIAbility component
- Starting the ServiceExtensionAbility and DataShareExtensionAbility components
- Using **startAbilityByCall()** to start the UIAbility component - Using **startAbilityByCall()** to start the UIAbility component
![component-startup-rules](figures/component-startup-inter-stage.png) ![component-startup-rules](figures/component-startup-inter-stage.png)
...@@ -8,6 +8,10 @@ This topic describes how the two application components of the stage model start ...@@ -8,6 +8,10 @@ This topic describes how the two application components of the stage model start
A UIAbility starts a PageAbility in the same way as it starts another UIAbility. A UIAbility starts a PageAbility in the same way as it starts another UIAbility.
> **NOTE**
>
> In the FA model, **abilityName** consists of **bundleName** and **AbilityName**. For details, see the code snippet below.
```ts ```ts
import UIAbility from '@ohos.app.ability.UIAbility'; import UIAbility from '@ohos.app.ability.UIAbility';
...@@ -25,7 +29,7 @@ export default class EntryAbility extends UIAbility { ...@@ -25,7 +29,7 @@ export default class EntryAbility extends UIAbility {
}); });
let want = { let want = {
bundleName: "com.ohos.fa", bundleName: "com.ohos.fa",
abilityName: "EntryAbility", abilityName: "com.ohos.fa.EntryAbility",
}; };
this.context.startAbility(want).then(() => { this.context.startAbility(want).then(() => {
console.info('Start Ability successfully.'); console.info('Start Ability successfully.');
......
...@@ -14,7 +14,7 @@ import featureAbility from '@ohos.ability.featureAbility'; ...@@ -14,7 +14,7 @@ import featureAbility from '@ohos.ability.featureAbility';
let parameter = { let parameter = {
"want": { "want": {
bundleName: "com.ohos.stage", bundleName: "com.ohos.stage",
abilityName: "com.ohos.stage.EntryAbility" abilityName: "EntryAbility"
} }
}; };
featureAbility.startAbility(parameter).then((code) => { featureAbility.startAbility(parameter).then((code) => {
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
## Types of Want ## Types of Want
- **Explicit Want**: If **abilityName** and **bundleName** are specified in the **want** parameter when starting an an application component, explicit Want is used. - **Explicit Want**: If **abilityName** and **bundleName** are specified in the **want** parameter when starting an application component, explicit Want is used.
Explicit Want is usually used to start a known target application component in the same application. The target application component is started by specifying **bundleName** of the application where the target application component is located and **abilityName** in the **Want** object. When there is an explicit object to process the request, explicit Want is a simple and effective way to start the target application component. Explicit Want is usually used to start a known target application component in the same application. The target application component is started by specifying **bundleName** of the application where the target application component is located and **abilityName** in the **Want** object. When there is an explicit object to process the request, explicit Want is a simple and effective way to start the target application component.
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
} }
``` ```
- **Implicit Want**: If **abilityName** is not specified in the **want** parameter when starting the an application component, implicit Want is used. - **Implicit Want**: If **abilityName** is not specified in the **want** parameter when starting an application component, implicit Want is used.
Implicit Want can be used when the object used to process the request is unclear and the current application wants to use a capability (defined by the [skills tag](../quick-start/module-configuration-file.md#skills)) provided by another application. The system matches all applications that declare to support the capability. For example, for a link open request, the system matches all applications that support the request and provides the available ones for users to select. Implicit Want can be used when the object used to process the request is unclear and the current application wants to use a capability (defined by the [skills tag](../quick-start/module-configuration-file.md#skills)) provided by another application. The system matches all applications that declare to support the capability. For example, for a link open request, the system matches all applications that support the request and provides the available ones for users to select.
...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
> - An application component that meets the conditions is matched. That application component is started. > - An application component that meets the conditions is matched. That application component is started.
> - Multiple application components that meet the conditions are matched. A dialog box is displayed for users to select one of them. > - Multiple application components that meet the conditions are matched. A dialog box is displayed for users to select one of them.
> >
> - If the **want** parameter passed does not contain **abilityName** or **bundleName**, the ServiceExtensionAbility components of all applications cannot be started through implicit Want. > - In the scenario for starting the ServiceExtensionAbility component:
> - If the **want** parameter passed in contains **abilityName**, the ServiceExtensionAbility component cannot be started through implicit Want.
> >
> - If the **want** parameter passed contains **bundleName**, the **startServiceExtensionAbility()** method can be used to implicitly start ServiceExtensionAbility. By default, ServiceExtensionAbility with the highest priority is returned. If all the matching ServiceExtensionAbility components have the same priority, the first ServiceExtensionAbility is returned. > - If the **want** parameter passed in contains **bundleName**, the **startServiceExtensionAbility()** method can be used to implicitly start the ServiceExtensionAbility component. By default, the ServiceExtensionAbility component with the highest priority is returned. If all the matching ServiceExtensionAbility components have the same priority, the first ServiceExtensionAbility component is returned.
...@@ -15,6 +15,7 @@ If a task does not need to occupy a background thread for a long time (3 minutes ...@@ -15,6 +15,7 @@ If a task does not need to occupy a background thread for a long time (3 minutes
1. Implement the logic of image processing. 1. Implement the logic of image processing.
2. Segment the data, and initiate associated task scheduling through task groups. 2. Segment the data, and initiate associated task scheduling through task groups.
Create a [task group](../reference/apis/js-apis-taskpool.md#taskgroup10), call [addTask()](../reference/apis/js-apis-taskpool.md#addtask10) to add tasks, call [execute()](../reference/apis/js-apis-taskpool.md#taskpoolexecute10) to execute the tasks in the task group, and set [a high priority](../reference/apis/js-apis-taskpool.md#priority) for the task group. After all the tasks in the task group are complete, the histogram processing result is returned simultaneously. Create a [task group](../reference/apis/js-apis-taskpool.md#taskgroup10), call [addTask()](../reference/apis/js-apis-taskpool.md#addtask10) to add tasks, call [execute()](../reference/apis/js-apis-taskpool.md#taskpoolexecute10) to execute the tasks in the task group, and set [a high priority](../reference/apis/js-apis-taskpool.md#priority) for the task group. After all the tasks in the task group are complete, the histogram processing result is returned simultaneously.
3. Summarize and process the result arrays. 3. Summarize and process the result arrays.
...@@ -78,7 +79,7 @@ The following uses the training of a region-specific house price prediction mode ...@@ -78,7 +79,7 @@ The following uses the training of a region-specific house price prediction mode
![newWorker](figures/newWorker.png) ![newWorker](figures/newWorker.png)
2. In the main thread, call [ThreadWorker()](../reference/apis/js-apis-worker.md#threadworker9) to create a **Worker** object. The calling thread is the host thread. 2. In the main thread, call [constructor()](../reference/apis/js-apis-worker.md#constructor9) of **ThreadWorker** to create a **Worker** object. The calling thread is the host thread.
```js ```js
import worker from '@ohos.worker'; import worker from '@ohos.worker';
...@@ -167,24 +168,22 @@ The following uses the training of a region-specific house price prediction mode ...@@ -167,24 +168,22 @@ The following uses the training of a region-specific house price prediction mode
6. After the task is completed in the worker thread, destroy the worker thread. The worker thread can be destroyed by itself or the host thread. Then, call [onexit()](../reference/apis/js-apis-worker.md#onexit9) in the host thread to define the processing logic after the worker thread is destroyed. 6. After the task is completed in the worker thread, destroy the worker thread. The worker thread can be destroyed by itself or the host thread. Then, call [onexit()](../reference/apis/js-apis-worker.md#onexit9) in the host thread to define the processing logic after the worker thread is destroyed.
```js ```js
// After the worker thread is destroyed, execute the onexit() callback. // After the worker thread is destroyed, execute the onexit() callback.
workerInstance.onexit = function() { workerInstance.onexit = function() {
console.info("main thread terminate"); console.info("main thread terminate");
} }
``` ```
In the host thread, call [terminate()](../reference/apis/js-apis-worker.md#terminate9) to destroy the worker thread and stop the worker thread from receiving messages.
Method 1: In the host thread, call [terminate()](../reference/apis/js-apis-worker.md#terminate9) to destroy the worker thread and stop the worker thread from receiving messages.
```js ```js
// Destroy the worker thread. // Destroy the worker thread.
workerInstance.terminate(); workerInstance.terminate();
``` ```
In the worker thread, call [close()](../reference/apis/js-apis-worker.md#close9) to destroy the worker thread and stop the worker thread from receiving messages.
Method 2: In the worker thread, call [close()](../reference/apis/js-apis-worker.md#close9) to destroy the worker thread and stop the worker thread from receiving messages.
```js ```js
// Destroy the worker thread. // Destroy the worker thread.
workerPort.close(); workerPort.close();
......
...@@ -44,14 +44,14 @@ The APIs provided by **Vector** are deprecated since API version 9. You are advi ...@@ -44,14 +44,14 @@ The APIs provided by **Vector** are deprecated since API version 9. You are advi
| Accessing elements| Use **vec\[index]** to obtain the value at a given position (specified by **index**).| | Accessing elements| Use **vec\[index]** to obtain the value at a given position (specified by **index**).|
| Accessing elements| Use **get(index: number)** to obtain the element at a given position (specified by **index**).| | Accessing elements| Use **get(index: number)** to obtain the element at a given position (specified by **index**).|
| Accessing elements| Use **getLastElement()** to obtain the last element in this container.| | Accessing elements| Use **getLastElement()** to obtain the last element in this container.|
| Accessing elements| Use **getlndexOf(element: T)** to obtain the index of the first occurrence of the specified element.| | Accessing elements| Use **getIndexOf(element: T)** to obtain the index of the first occurrence of the specified element.|
| Accessing elements| Use **getLastlndexOf(element: T)** to obtain the index of the last occurrence of the specified element.| | Accessing elements| Use **getLastIndexOf(element: T)** to obtain the index of the last occurrence of the specified element.|
| Accessing elements| Use **forEach(callbackFn: (value: T, index?: number, Vector?: Vector&lt;T&gt;) =&gt; void, thisArg?: Object)** to traverse the elements in this container.| | Accessing elements| Use **forEach(callbackFn: (value: T, index?: number, Vector?: Vector&lt;T&gt;) =&gt; void, thisArg?: Object)** to traverse the elements in this container.|
| Accessing elements| Use **\[Symbol.iterator]():IterableIterator&lt;T&gt;** for data access.| | Accessing elements| Use **\[Symbol.iterator]():IterableIterator&lt;T&gt;** for data access.|
| Modifying elements| Use **vec\[index]=xxx** to change the value at a given position (specified by **index**).| | Modifying elements| Use **vec\[index]=xxx** to change the value at a given position (specified by **index**).|
| Modifying elements| Use **set(index: number, element: T)** to replace an element at a given position (specified by **index**) with a given element.| | Modifying elements| Use **set(index: number, element: T)** to replace an element at a given position (specified by **index**) with a given element.|
| Modifying elements| Use **setLength(newSize: number)** to set the size of this container.| | Modifying elements| Use **setLength(newSize: number)** to set the size of this container.|
| Deleting elements| Use **removeBylndex(index: number)** to remove the value at a given position (specified by **index**).| | Deleting elements| Use **removeByIndex(index: number)** to remove the value at a given position (specified by **index**).|
| Deleting elements| Use **remove(element: T)** to remove the first occurrence of the specified element.| | Deleting elements| Use **remove(element: T)** to remove the first occurrence of the specified element.|
| Deleting elements| Use **removeByRange(fromIndex: number, toIndex: number)** to remove all of the elements within a range.| | Deleting elements| Use **removeByRange(fromIndex: number, toIndex: number)** to remove all of the elements within a range.|
...@@ -74,14 +74,14 @@ You are advised to use **List** for frequent insertion and removal operations. ...@@ -74,14 +74,14 @@ You are advised to use **List** for frequent insertion and removal operations.
| Accessing elements| Use **get(index: number)** to obtain the element at a given position (specified by **index**).| | Accessing elements| Use **get(index: number)** to obtain the element at a given position (specified by **index**).|
| Accessing elements| Use **getFirst()** to obtain the first element in this container.| | Accessing elements| Use **getFirst()** to obtain the first element in this container.|
| Accessing elements| Use **getLast()** to obtain the last element in this container.| | Accessing elements| Use **getLast()** to obtain the last element in this container.|
| Accessing elements| Use **getlndexOf(element: T)** to obtain the index of the first occurrence of the specified element.| | Accessing elements| Use **getIndexOf(element: T)** to obtain the index of the first occurrence of the specified element.|
| Accessing elements| Use **getLastlndexOf(element: T)** to obtain the index of the last occurrence of the specified element.| | Accessing elements| Use **getLastIndexOf(element: T)** to obtain the index of the last occurrence of the specified element.|
| Accessing elements| Use **forEach(callbackfn: (value: T, index?: number, list?: List&lt;T&gt;)=&gt; void, thisArg?: Object)** to traverse the elements in this container.| | Accessing elements| Use **forEach(callbackfn: (value: T, index?: number, list?: List&lt;T&gt;)=&gt; void, thisArg?: Object)** to traverse the elements in this container.|
| Accessing elements| Use **\[Symbol.iterator]():IterableIterator&lt;T&gt;** for data access.| | Accessing elements| Use **\[Symbol.iterator]():IterableIterator&lt;T&gt;** for data access.|
| Modifying elements| Use **list\[index] = xxx** to change the value at a given position (specified by **index**).| | Modifying elements| Use **list\[index] = xxx** to change the value at a given position (specified by **index**).|
| Modifying elements| Use **set(index: number, element: T)** to replace an element at a given position (specified by **index**) with a given element.| | Modifying elements| Use **set(index: number, element: T)** to replace an element at a given position (specified by **index**) with a given element.|
| Modifying elements| Use **replaceAllElements(callbackFn:(value: T,index?: number,list?: List&lt;T&gt;)=&gt;T,thisArg?: Object)** to replace all elements in this container with new elements.| | Modifying elements| Use **replaceAllElements(callbackFn:(value: T,index?: number,list?: List&lt;T&gt;)=&gt;T,thisArg?: Object)** to replace all elements in this container with new elements.|
| Deleting elements| Use **removeBylndex(index: number)** to remove the value at a given position (specified by **index**).| | Deleting elements| Use **removeByIndex(index: number)** to remove the value at a given position (specified by **index**).|
| Deleting elements| Use **remove(element: T)** to remove the first occurrence of the specified element.| | Deleting elements| Use **remove(element: T)** to remove the first occurrence of the specified element.|
...@@ -105,13 +105,13 @@ You are advised to use **LinkedList** for frequent insertion and removal operati ...@@ -105,13 +105,13 @@ You are advised to use **LinkedList** for frequent insertion and removal operati
| Accessing elements| Use **get(index: number)** to obtain the element at a given position (specified by **index**).| | Accessing elements| Use **get(index: number)** to obtain the element at a given position (specified by **index**).|
| Accessing elements| Use **getFirst()** to obtain the first element in this container.| | Accessing elements| Use **getFirst()** to obtain the first element in this container.|
| Accessing elements| Use **getLast()** to obtain the last element in this container.| | Accessing elements| Use **getLast()** to obtain the last element in this container.|
| Accessing elements| Use **getlndexOf(element: T)** to obtain the index of the first occurrence of the specified element.| | Accessing elements| Use **getIndexOf(element: T)** to obtain the index of the first occurrence of the specified element.|
| Accessing elements| Use **getLastlndexOf(element: T)** to obtain the index of the last occurrence of the specified element.| | Accessing elements| Use **getLastIndexOf(element: T)** to obtain the index of the last occurrence of the specified element.|
| Accessing elements| Use **forEach(callbackFn: (value: T, index?: number, list?: LinkedList&lt;T&gt;) =&gt; void, thisArg?: Object)** to traverse the elements in this container.| | Accessing elements| Use **forEach(callbackFn: (value: T, index?: number, list?: LinkedList&lt;T&gt;) =&gt; void, thisArg?: Object)** to traverse the elements in this container.|
| Accessing elements| Use **\[Symbol.iterator]():IterableIterator&lt;T&gt;** for data access.| | Accessing elements| Use **\[Symbol.iterator]():IterableIterator&lt;T&gt;** for data access.|
| Modifying elements| Use **list\[index]=xxx** to change the value at a given position (specified by **index**).| | Modifying elements| Use **list\[index]=xxx** to change the value at a given position (specified by **index**).|
| Modifying elements| Use **set(index: number, element: T)** to replace an element at a given position (specified by **index**) with a given element.| | Modifying elements| Use **set(index: number, element: T)** to replace an element at a given position (specified by **index**) with a given element.|
| Deleting elements| Use **removeBylndex(index: number)** to remove the value at a given position (specified by **index**).| | Deleting elements| Use **removeByIndex(index: number)** to remove the value at a given position (specified by **index**).|
| Deleting elements| Use **remove(element: T)** to remove the first occurrence of the specified element.| | Deleting elements| Use **remove(element: T)** to remove the first occurrence of the specified element.|
......
...@@ -12,7 +12,7 @@ Due to the memory isolation feature of the actor model, cross-thread serializati ...@@ -12,7 +12,7 @@ Due to the memory isolation feature of the actor model, cross-thread serializati
## Data Transfer Objects ## Data Transfer Objects
Data objects that can be transferred are classified into three types: [common objects](#common-objects), [transferable objects](#transferable-objects), and [shared objects](#shared-objects). Data objects that can be transferred are classified into the following types: [common objects](#common-objects), [transferable objects](#transferable-objects), [shared objects](#shared-objects), and [native binding objects](#native-binding-objects).
### Common Objects ### Common Objects
...@@ -24,7 +24,7 @@ The following object types are supported: basic types except Symbol, Date, Strin ...@@ -24,7 +24,7 @@ The following object types are supported: basic types except Symbol, Date, Strin
### Transferable Objects ### Transferable Objects
Transferable objects are serialized through address transfer. It transfers the ownership of an object of the ArrayBuffer type object, rather than the content in it. After the ownership is transferred, the object becomes unavailable in the sender and can be used only in the receiver. Transferable objects are serialized through address transfer. It transfers the ownership of an object of the ArrayBuffer type, rather than the content in it. After the ownership is transferred, the object becomes unavailable in the sender and can be used only in the receiver.
```js ```js
...@@ -47,6 +47,15 @@ If multiple operations are simultaneously performed to modify data stored in an ...@@ -47,6 +47,15 @@ If multiple operations are simultaneously performed to modify data stored in an
let sharedBuffer = new SharedArrayBuffer(1024); let sharedBuffer = new SharedArrayBuffer(1024);
``` ```
### Native Binding Objects
Native binding objects are provided by the system. They are bound to underlying system services and enables direct access to these services.
Currently, native bound objects that support serialization include [Context](../application-models/application-context-stage.md) and [RemoteObject](../reference/apis/js-apis-rpc.md#remoteobject).
The **Context** object provides the context information about an application component. It provides a way to access system services and resources so that the application component can interact with the system. For details about how to obtain context information, see [Context (Stage Model)](../application-models/application-context-stage.md).
The **RemoteObject** object implements remote communication. It transfers the reference of an object between processes so that these processes can share the status and methods of the object. The service provider must inherit this class. For details about how to create a **RemoteObject** object, see [RemoteObject](../reference/apis/js-apis-rpc.md#remoteobject).
## TaskPool and Worker ## TaskPool and Worker
......
...@@ -52,9 +52,9 @@ You are advised to use **HashSet** when you need a set that has only unique elem ...@@ -52,9 +52,9 @@ You are advised to use **HashSet** when you need a set that has only unique elem
| Adding elements| Use **add(value: T)** to add a value to this container.| | Adding elements| Use **add(value: T)** to add a value to this container.|
| Accessing elements| Use **values()** to return an iterator that contains all the values in this container.| | Accessing elements| Use **values()** to return an iterator that contains all the values in this container.|
| Accessing elements| Use **entries()** to return an iterator that contains all the elements in this container.| | Accessing elements| Use **entries()** to return an iterator that contains all the elements in this container.|
| Accessing elements| Use **forEach(callbackFn: (value?: T, key?: T, set?: HashSet<T>) => void, thisArg?: Object)** to traverse the elements in this container.| | Accessing elements| Use **forEach(callbackFn: (value?: T, key?: T, set?: HashSet\<T>) => void, thisArg?: Object)** to traverse the elements in this container.|
| Accessing elements| Use **\[Symbol.iterator]():IterableIterator&lt;T&gt;** for data access.| | Accessing elements| Use **\[Symbol.iterator]():IterableIterator&lt;T&gt;** for data access.|
| Modifying elements| Use **forEach(callbackFn: (value?: T, key?: T, set?: HashSet<T>) => void, thisArg?: Object)** to change a value in this container.| | Modifying elements| Use **forEach(callbackFn: (value?: T, key?: T, set?: HashSet\<T>) => void, thisArg?: Object)** to change a value in this container.|
| Deleting elements| Use **remove(value: T)** to remove a value.| | Deleting elements| Use **remove(value: T)** to remove a value.|
| Deleting elements| Use **clear()** to clear this container.| | Deleting elements| Use **clear()** to clear this container.|
...@@ -109,9 +109,9 @@ You are advised to use **TreeSet** when you need to store data in sorted order. ...@@ -109,9 +109,9 @@ You are advised to use **TreeSet** when you need to store data in sorted order.
| Accessing elements| Use **entries()** to return an iterator that contains all the elements in this container.| | Accessing elements| Use **entries()** to return an iterator that contains all the elements in this container.|
| Accessing elements| Use **getFirstValue()** to obtain the first value in this container.| | Accessing elements| Use **getFirstValue()** to obtain the first value in this container.|
| Accessing elements| Use **getLastValue()** to obtain the last value in this container.| | Accessing elements| Use **getLastValue()** to obtain the last value in this container.|
| Accessing elements| Use **forEach(callbackFn: (value?: T, key?: T, set?: TreeSet<T>) => void, thisArg?: Object)** to traverse the elements in this container.| | Accessing elements| Use **forEach(callbackFn: (value?: T, key?: T, set?: TreeSet\<T>) => void, thisArg?: Object)** to traverse the elements in this container.|
| Accessing elements| Use **\[Symbol.iterator]():IterableIterator&lt;T&gt;** for data access.| | Accessing elements| Use **\[Symbol.iterator]():IterableIterator&lt;T&gt;** for data access.|
| Modifying elements| Use **forEach(callbackFn: (value?: T, key?: T, set?: TreeSet<T>) => void, thisArg?: Object)** to change a value in this container.| | Modifying elements| Use **forEach(callbackFn: (value?: T, key?: T, set?: TreeSet\<T>) => void, thisArg?: Object)** to change a value in this container.|
| Deleting elements| Use **remove(value: T)** to remove a value.| | Deleting elements| Use **remove(value: T)** to remove a value.|
| Deleting elements| Use **clear()** to clear this container.| | Deleting elements| Use **clear()** to clear this container.|
...@@ -169,9 +169,9 @@ You are advised to use **LightWeightSet** when you need a set that has only uniq ...@@ -169,9 +169,9 @@ You are advised to use **LightWeightSet** when you need a set that has only uniq
| Accessing elements| Use **values()** to return an iterator that contains all the values in this container.| | Accessing elements| Use **values()** to return an iterator that contains all the values in this container.|
| Accessing elements| Use **entries()** to return an iterator that contains all the elements in this container.| | Accessing elements| Use **entries()** to return an iterator that contains all the elements in this container.|
| Accessing elements| Use **getValueAt(index: number)** to obtain the value of an element at a given position (specified by **index**).| | Accessing elements| Use **getValueAt(index: number)** to obtain the value of an element at a given position (specified by **index**).|
| Accessing elements| Use **forEach(callbackFn: (value?: T, key?: T, set?: LightWeightSet<T>) => void, thisArg?: Object)** to traverse the elements in this container.| | Accessing elements| Use **forEach(callbackFn: (value?: T, key?: T, set?: LightWeightSet\<T>) => void, thisArg?: Object)** to traverse the elements in this container.|
| Accessing elements| Use **\[Symbol.iterator]():IterableIterator&lt;T&gt;** for data access.| | Accessing elements| Use **\[Symbol.iterator]():IterableIterator&lt;T&gt;** for data access.|
| Modifying elements| Use **forEach(callbackFn: (value?: T, key?: T, set?: LightWeightSet<T>) => void, thisArg?: Object)** to change a value in this container.| | Modifying elements| Use **forEach(callbackFn: (value?: T, key?: T, set?: LightWeightSet\<T>) => void, thisArg?: Object)** to change a value in this container.|
| Deleting elements| Use **remove(key: K)** to remove an element with the specified key.| | Deleting elements| Use **remove(key: K)** to remove an element with the specified key.|
| Deleting elements| Use **removeAt(index: number)** to remove an element at a given position (specified by **index**).| | Deleting elements| Use **removeAt(index: number)** to remove an element at a given position (specified by **index**).|
| Deleting elements| Use **clear()** to clear this container.| | Deleting elements| Use **clear()** to clear this container.|
...@@ -197,10 +197,10 @@ You are advised to use PlainArray when you need to store KV pairs whose keys are ...@@ -197,10 +197,10 @@ You are advised to use PlainArray when you need to store KV pairs whose keys are
| Accessing elements| Use **getIndexOfValue(value: T)** to obtain the index of the specified value.| | Accessing elements| Use **getIndexOfValue(value: T)** to obtain the index of the specified value.|
| Accessing elements| Use **getKeyAt(index: number)** to obtain the key of an element at a given position (specified by **index**).| | Accessing elements| Use **getKeyAt(index: number)** to obtain the key of an element at a given position (specified by **index**).|
| Accessing elements| Use **getValueAt(index: number)** to obtain the value of an element at a given position (specified by **index**).| | Accessing elements| Use **getValueAt(index: number)** to obtain the value of an element at a given position (specified by **index**).|
| Accessing elements| Use **forEach(callbackFn: (value: T, index?: number, PlainArray?: PlainArray<T>) => void, thisArg?: Object)** to traverse the elements in this container.| | Accessing elements| Use **forEach(callbackFn: (value: T, index?: number, PlainArray?: PlainArray\<T>) => void, thisArg?: Object)** to traverse the elements in this container.|
| Accessing elements| Use **\[Symbol.iterator]():IterableIterator&lt;[number, T]&gt;** for data access.| | Accessing elements| Use **\[Symbol.iterator]():IterableIterator&lt;[number, T]&gt;** for data access.|
| Modifying elements| Use **setValueAt(index:number, value: T)** to change the value of an element at a given position (specified by **index**).| | Modifying elements| Use **setValueAt(index:number, value: T)** to change the value of an element at a given position (specified by **index**).|
| Modifying elements| Use **forEach(callbackFn: (value: T, index?: number, PlainArray?: PlainArray<T>) => void, thisArg?: Object)** to modify an element in this container.| | Modifying elements| Use **forEach(callbackFn: (value: T, index?: number, PlainArray?: PlainArray\<T>) => void, thisArg?: Object)** to modify an element in this container.|
| Deleting elements| Use **remove(key: number)** to remove an element with the specified key.| | Deleting elements| Use **remove(key: number)** to remove an element with the specified key.|
| Deleting elements| Use **removeAt(index: number)** to remove an element at a given position (specified by **index**).| | Deleting elements| Use **removeAt(index: number)** to remove an element at a given position (specified by **index**).|
| Deleting elements| Use **removeRangeFrom(index: number, size: number)** to remove elements in a specified range.| | Deleting elements| Use **removeRangeFrom(index: number, size: number)** to remove elements in a specified range.|
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
Data transferred in XML format must be parsed in actual use. Generally, three types of elements need to be parsed, as described in [Parsing XML Tags and Tag Values](#parsing-xml-tags-and-tag-values), [Parsing XML Attributes and Attribute Values](#parsing-xml-attributes-and-attribute-values), and [Parsing XML Event Types and Element Depths](#parsing-xml-event-types-and-element-depths). Data transferred in XML format must be parsed in actual use. Generally, three types of elements need to be parsed, as described in [Parsing XML Tags and Tag Values](#parsing-xml-tags-and-tag-values), [Parsing XML Attributes and Attribute Values](#parsing-xml-attributes-and-attribute-values), and [Parsing XML Event Types and Element Depths](#parsing-xml-event-types-and-element-depths).
The **xml** module provides the **XmlPullParser** class to parse XML files. The input is an object of the ArrayBufffer or DataView type containing XML text, and the output is the parsed information. The **xml** module provides the **XmlPullParser** class to parse XML files. The input is an object of the ArrayBuffer or DataView type containing XML text, and the output is the parsed information.
**Table 1** XML parsing options **Table 1** XML parsing options
......
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
- [Ethernet Connection](net-ethernet.md) - [Ethernet Connection](net-ethernet.md)
- [Network Connection Management](net-connection-manager.md) - [Network Connection Management](net-connection-manager.md)
- [mDNS Management](net-mdns.md) - [mDNS Management](net-mdns.md)
- [Traffic Management](net-statistics.md)
- [VPN Management](net-vpn.md)
- IPC & RPC - IPC & RPC
- [IPC & RPC Overview](ipc-rpc-overview.md) - [IPC & RPC Overview](ipc-rpc-overview.md)
- [IPC & RPC Development](ipc-rpc-development-guideline.md) - [IPC & RPC Development](ipc-rpc-development-guideline.md)
......
# HTTP Data Request # HTTP Data Request
## When to Use ## Overview
An application can initiate a data request over HTTP. Common HTTP methods include **GET**, **POST**, **OPTIONS**, **HEAD**, **PUT**, **DELETE**, **TRACE**, and **CONNECT**. An application can initiate a data request over HTTP. Common HTTP methods include **GET**, **POST**, **OPTIONS**, **HEAD**, **PUT**, **DELETE**, **TRACE**, and **CONNECT**.
...@@ -18,7 +18,7 @@ The following table provides only a simple description of the related APIs. For ...@@ -18,7 +18,7 @@ The following table provides only a simple description of the related APIs. For
| ----------------------------------------- | ----------------------------------- | | ----------------------------------------- | ----------------------------------- |
| createHttp() | Creates an HTTP request. | | createHttp() | Creates an HTTP request. |
| request() | Initiates an HTTP request to a given URL. | | request() | Initiates an HTTP request to a given URL. |
| request2()<sup>10+</sup> | Initiates an HTTP network request based on the URL and returns a streaming response.| | requestInStream()<sup>10+</sup> | Initiates an HTTP network request to a given URL and returns a streaming response.|
| destroy() | Destroys an HTTP request. | | destroy() | Destroys an HTTP request. |
| on(type: 'headersReceive') | Registers an observer for HTTP Response Header events. | | on(type: 'headersReceive') | Registers an observer for HTTP Response Header events. |
| off(type: 'headersReceive') | Unregisters the observer for HTTP Response Header events.| | off(type: 'headersReceive') | Unregisters the observer for HTTP Response Header events.|
...@@ -27,8 +27,8 @@ The following table provides only a simple description of the related APIs. For ...@@ -27,8 +27,8 @@ The following table provides only a simple description of the related APIs. For
| off\('dataReceive'\)<sup>10+</sup> | Unregisters the observer for events indicating receiving of HTTP streaming responses. | | off\('dataReceive'\)<sup>10+</sup> | Unregisters the observer for events indicating receiving of HTTP streaming responses. |
| on\('dataEnd'\)<sup>10+</sup> | Registers an observer for events indicating completion of receiving HTTP streaming responses. | | on\('dataEnd'\)<sup>10+</sup> | Registers an observer for events indicating completion of receiving HTTP streaming responses. |
| off\('dataEnd'\)<sup>10+</sup> | Unregisters the observer for events indicating completion of receiving HTTP streaming responses.| | off\('dataEnd'\)<sup>10+</sup> | Unregisters the observer for events indicating completion of receiving HTTP streaming responses.|
| on\('dataProgress'\)<sup>10+</sup> | Registers an observer for events indicating progress of receiving HTTP streaming responses. | | on\('dataReceiveProgress'\)<sup>10+</sup> | Registers an observer for events indicating progress of receiving HTTP streaming responses. |
| off\('dataProgress'\)<sup>10+</sup> | Unregisters the observer for events indicating progress of receiving HTTP streaming responses.| | off\('dataReceiveProgress'\)<sup>10+</sup> | Unregisters the observer for events indicating progress of receiving HTTP streaming responses.|
## How to Develop request APIs ## How to Develop request APIs
...@@ -53,6 +53,7 @@ httpRequest.on('headersReceive', (header) => { ...@@ -53,6 +53,7 @@ httpRequest.on('headersReceive', (header) => {
}); });
httpRequest.request( httpRequest.request(
// Customize EXAMPLE_URL in extraData on your own. It is up to you whether to add parameters to the URL. // Customize EXAMPLE_URL in extraData on your own. It is up to you whether to add parameters to the URL.
"EXAMPLE_URL",
{ {
method: http.RequestMethod.POST, // Optional. The default value is http.RequestMethod.GET. method: http.RequestMethod.POST, // Optional. The default value is http.RequestMethod.GET.
// You can add header fields based on service requirements. // You can add header fields based on service requirements.
...@@ -81,7 +82,7 @@ httpRequest.request( ...@@ -81,7 +82,7 @@ httpRequest.request(
// Call the destroy() method to release resources after HttpRequest is complete. // Call the destroy() method to release resources after HttpRequest is complete.
httpRequest.destroy(); httpRequest.destroy();
} else { } else {
console.info('error:' + JSON.stringify(err)); console.error('error:' + JSON.stringify(err));
// Unsubscribe from HTTP Response Header events. // Unsubscribe from HTTP Response Header events.
httpRequest.off('headersReceive'); httpRequest.off('headersReceive');
// Call the destroy() method to release resources after HttpRequest is complete. // Call the destroy() method to release resources after HttpRequest is complete.
...@@ -91,12 +92,12 @@ httpRequest.request( ...@@ -91,12 +92,12 @@ httpRequest.request(
); );
``` ```
## How to Develop request2 APIs ## How to Develop requestInStream APIs
1. Import the **http** namespace from **@ohos.net.http.d.ts**. 1. Import the **http** namespace from **@ohos.net.http.d.ts**.
2. Call **createHttp()** to create an **HttpRequest** object. 2. Call **createHttp()** to create an **HttpRequest** object.
3. Depending on your need, call **on()** of the **HttpRequest** object to subscribe to HTTP response header events as well as events indicating receiving of HTTP streaming responses, progress of receiving HTTP streaming responses, and completion of receiving HTTP streaming responses. 3. Depending on your need, call **on()** of the **HttpRequest** object to subscribe to HTTP response header events as well as events indicating receiving of HTTP streaming responses, progress of receiving HTTP streaming responses, and completion of receiving HTTP streaming responses.
4. Call **request2()** to initiate a network request. You need to pass in the URL and optional parameters of the HTTP request. 4. Call **requestInStream()** to initiate a network request. You need to pass in the URL and optional parameters of the HTTP request.
5. Parse the returned response code as needed. 5. Parse the returned response code as needed.
6. Call **off()** of the **HttpRequest** object to unsubscribe from the related events. 6. Call **off()** of the **HttpRequest** object to unsubscribe from the related events.
7. Call **httpRequest.destroy()** to release resources after the request is processed. 7. Call **httpRequest.destroy()** to release resources after the request is processed.
...@@ -122,11 +123,11 @@ httpRequest.on('dataEnd', () => { ...@@ -122,11 +123,11 @@ httpRequest.on('dataEnd', () => {
console.info('No more data in response, data receive end'); console.info('No more data in response, data receive end');
}); });
// Subscribe to events indicating progress of receiving HTTP streaming responses. // Subscribe to events indicating progress of receiving HTTP streaming responses.
httpRequest.on('dataProgress', (data) => { httpRequest.on('dataReceiveProgress', (data) => {
console.log("dataProgress receiveSize:" + data.receiveSize + ", totalSize:" + data.totalSize); console.log("dataReceiveProgress receiveSize:" + data.receiveSize + ", totalSize:" + data.totalSize);
}); });
httpRequest.request2( httpRequest.requestInStream(
// Customize EXAMPLE_URL in extraData on your own. It is up to you whether to add parameters to the URL. // Customize EXAMPLE_URL in extraData on your own. It is up to you whether to add parameters to the URL.
"EXAMPLE_URL", "EXAMPLE_URL",
{ {
...@@ -146,14 +147,14 @@ httpRequest.request2( ...@@ -146,14 +147,14 @@ httpRequest.request2(
readTimeout: 60000, // Optional. The default value is 60000, in ms. If a large amount of data needs to be transmitted, you are advised to set this parameter to a larger value to ensure normal data transmission. readTimeout: 60000, // Optional. The default value is 60000, in ms. If a large amount of data needs to be transmitted, you are advised to set this parameter to a larger value to ensure normal data transmission.
usingProtocol: http.HttpProtocol.HTTP1_1, // Optional. The default protocol type is automatically specified by the system. usingProtocol: http.HttpProtocol.HTTP1_1, // Optional. The default protocol type is automatically specified by the system.
}, (err, data) => { }, (err, data) => {
console.info('error:' + JSON.stringify(err)); console.error('error:' + JSON.stringify(err));
console.info('ResponseCode :' + JSON.stringify(data)); console.info('ResponseCode :' + JSON.stringify(data));
// Unsubscribe from HTTP Response Header events. // Unsubscribe from HTTP Response Header events.
httpRequest.off('headersReceive'); httpRequest.off('headersReceive');
// Unregister the observer for events indicating receiving of HTTP streaming responses. // Unregister the observer for events indicating receiving of HTTP streaming responses.
httpRequest.off('dataReceive'); httpRequest.off('dataReceive');
// Unregister the observer for events indicating progress of receiving HTTP streaming responses. // Unregister the observer for events indicating progress of receiving HTTP streaming responses.
httpRequest.off('dataProgress'); httpRequest.off('dataReceiveProgress');
// Unregister the observer for events indicating completion of receiving HTTP streaming responses. // Unregister the observer for events indicating completion of receiving HTTP streaming responses.
httpRequest.off('dataEnd'); httpRequest.off('dataEnd');
// Call the destroy() method to release resources after HttpRequest is complete. // Call the destroy() method to release resources after HttpRequest is complete.
...@@ -161,10 +162,3 @@ httpRequest.request2( ...@@ -161,10 +162,3 @@ httpRequest.request2(
} }
); );
``` ```
## 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)
# IPC & RPC Development Guidelines # IPC & RPC Development Guidelines
## When to Use ## Overview
IPC/RPC enables a proxy and a stub that run on different processes to communicate with each other, regardless of whether they run on the same or different devices. IPC/RPC enables a proxy and a stub that run on different processes to communicate with each other, regardless of whether they run on the same or different devices.
......
# Network Connection Management # Network Connection Management
## Introduction ## Overview
The Network Connection Management module provides basic network management capabilities, including management of Wi-Fi/cellular/Ethernet connection priorities, network quality evaluation, subscription to network connection status changes, query of network connection information, and DNS resolution. The Network Connection Management module provides basic network management capabilities, including management of Wi-Fi/cellular/Ethernet connection priorities, network quality evaluation, subscription to network connection status changes, query of network connection information, and DNS resolution.
> **NOTE** > **NOTE**
>
> To maximize the application running efficiency, most API calls are called asynchronously in callback or promise mode. The following code examples use the callback mode. For details about the APIs, see [sms API Reference](../reference/apis/js-apis-net-connection.md). > To maximize the application running efficiency, most API calls are called asynchronously in callback or promise mode. The following code examples use the callback mode. For details about the APIs, see [sms API Reference](../reference/apis/js-apis-net-connection.md).
## Basic Concepts ## Basic Concepts
...@@ -107,7 +108,7 @@ conn.on('netAvailable', (data => { ...@@ -107,7 +108,7 @@ conn.on('netAvailable', (data => {
// Listen to network status change events. If the network is unavailable, an on_netUnavailable event is returned. // Listen to network status change events. If the network is unavailable, an on_netUnavailable event is returned.
conn.on('netUnavailable', (data => { conn.on('netUnavailable', (data => {
console.log("net is unavailable, netId is " + data.netId); console.log("net is unavailable, data is " + JSON.stringify(data));
})); }));
// Register an observer for network status changes. // Register an observer for network status changes.
......
# Ethernet Connection # Ethernet Connection
## Introduction ## Overview
The Ethernet Connection module allows a device to access the Internet through a network cable. After a device is connected to the Ethernet through a network cable, the device can obtain a series of network attributes, such as the dynamically allocated IP address, subnet mask, gateway, and DNS. You can manually configure and obtain the network attributes of the device in static mode. The Ethernet Connection module allows a device to access the Internet through a network cable. After a device is connected to the Ethernet through a network cable, the device can obtain a series of network attributes, such as the dynamically allocated IP address, subnet mask, gateway, and DNS. You can manually configure and obtain the network attributes of the device in static mode.
> **NOTE** > **NOTE**
>
> To maximize the application running efficiency, most API calls are called asynchronously in callback or promise mode. The following code examples use the callback mode. For details about the APIs, see [sms API Reference](../reference/apis/js-apis-net-ethernet.md). > To maximize the application running efficiency, most API calls are called asynchronously in callback or promise mode. The following code examples use the callback mode. For details about the APIs, see [sms API Reference](../reference/apis/js-apis-net-ethernet.md).
## **Constraints** ## **Constraints**
......
# MDNS Management # MDNS Management
## Introduction ## Overview
Multicast DNS (mDNS) provides functions such as adding, removing, discovering, and resolving local services on a LAN. Multicast DNS (mDNS) provides functions such as adding, removing, discovering, and resolving local services on a LAN.
- Local service: a service provider on a LAN, for example, a printer or scanner. - Local service: a service provider on a LAN, for example, a printer or scanner.
......
# Network Sharing # Network Sharing
## Introduction ## Overview
The Network Sharing module allows you to share your device's Internet connection with other connected devices by means of Wi-Fi hotspot, Bluetooth, and USB sharing. It also allows you to query the network sharing state and shared mobile data volume. The Network Sharing module allows you to share your device's Internet connection with other connected devices by means of Wi-Fi hotspot, Bluetooth, and USB sharing. It also allows you to query the network sharing state and shared mobile data volume.
> **NOTE** > **NOTE**
>
> To maximize the application running efficiency, most API calls are called asynchronously in callback or promise mode. The following code examples use the callback mode. For details about the APIs, see [sms API Reference](../reference/apis/js-apis-net-sharing.md). > To maximize the application running efficiency, most API calls are called asynchronously in callback or promise mode. The following code examples use the callback mode. For details about the APIs, see [sms API Reference](../reference/apis/js-apis-net-sharing.md).
## Basic Concepts ## Basic Concepts
......
# Traffic Management # Traffic Management
## Introduction ## Overview
The traffic management module allows you to query real-time or historical data traffic by the specified network interface card (NIC) or user ID (UID). The traffic management module allows you to query real-time or historical data traffic by the specified network interface card (NIC) or user ID (UID).
...@@ -11,6 +11,7 @@ Its functions include: ...@@ -11,6 +11,7 @@ Its functions include:
- Subscribing to traffic change events by NIC or UID - Subscribing to traffic change events by NIC or UID
> **NOTE** > **NOTE**
>
> To maximize the application running efficiency, most API calls are called asynchronously in callback or promise mode. The following code examples use the callback mode. For details about the APIs, see [Traffic Management](../reference/apis/js-apis-net-statistics.md). > To maximize the application running efficiency, most API calls are called asynchronously in callback or promise mode. The following code examples use the callback mode. For details about the APIs, see [Traffic Management](../reference/apis/js-apis-net-statistics.md).
The following describes the development procedure specific to each application scenario. The following describes the development procedure specific to each application scenario.
......
# VPN Management
## Overview
A virtual private network (VPN) is a dedicated network established on a public network. On a VPN, the connection between any two nodes does not have an end-to-end physical link required by the traditional private network. Instead, user data is transmitted over a logical link because a VPN is a logical network deployed over the network platform (such as the Internet) provided by the public network service provider.
> **NOTE**
>
> To maximize the application running efficiency, most API calls are called asynchronously in callback or promise mode. The following code examples use the callback mode. For details about the APIs, see [Traffic Management](../reference/apis/js-apis-net-vpn.md).
The following describes the development procedure specific to each application scenario.
## Available APIs
For the complete list of APIs and example code, see [VPN Management](../reference/apis/js-apis-net-vpn.md).
| Type| API| Description|
| ---- | ---- | ---- |
| ohos.net.vpn | setUp(config: VpnConfig, callback: AsyncCallback\<number\>): void | Establishes a VPN. This API uses an asynchronous callback to return the result.|
| ohos.net.vpn | protect(socketFd: number, callback: AsyncCallback\<void\>): void | Enables VPN tunnel protection. This API uses an asynchronous callback to return the result.|
| ohos.net.vpn | destroy(callback: AsyncCallback\<void\>): void | Destroys a VPN. This API uses an asynchronous callback to return the result.|
## Starting a VPN
1. Establish a VPN tunnel. The following uses the UDP tunnel as an example.
2. Enable protection for the UDP tunnel.
3. Establish a VPN.
4. Process data of the virtual network interface card (vNIC), such as reading or writing data.
5. Destroy the VPN.
This example shows how to develop an application using native C++ code. For details, see [Simple Native C++ Example (ArkTS) (API9)] (https://gitee.com/openharmony/codelabs/tree/master/NativeAPI/NativeTemplateDemo).
The sample application consists of two parts: JS code and C++ code.
## JS Code
The JS code is used to implement the service logic, such as creating a tunnel, establishing a VPN, enabling VPN protection, and destroying a VPN.
```js
import hilog from '@ohos.hilog';
import vpn from '@ohos.net.vpn';
import UIAbility from '@ohos.app.ability.UIAbility';
import vpn_client from "libvpn_client.so"
class EntryAbility extends UIAbility {
onWindowStageCreate(windowStage) {
globalThis.context = this.context;
}
}
let TunnelFd = -1
let VpnConnection = vpn.createVpnConnection(globalThis.context)
@Entry
@Component
struct Index {
@State message: string = 'Test VPN'
//1. Establish a VPN tunnel. The following uses the UDP tunnel as an example.
CreateTunnel() {
TunnelFd = vpn_client.udpConnect("192.168.43.208", 8888)
}
// 2. Enable protection for the UDP tunnel.
Protect() {
VpnConnection.protect(TunnelFd).then(function () {
console.info("vpn Protect Success.")
}).catch(function (err) {
console.info("vpn Protect Failed " + JSON.stringify(err))
})
}
SetupVpn() {
let config = {
addresses: [{
address: {
address: "10.0.0.5",
family: 1
},
prefixLength: 24,
}],
routes: [],
mtu: 1400,
dnsAddresses: [
"114.114.114.114"
],
acceptedApplications: [],
refusedApplications: []
}
try {
// 3. Create a VPN.
VpnConnection.setUp(config, (error, data) => {
console.info("tunfd: " + JSON.stringify(data));
// 4. Process data of the virtual vNIC, such as reading or writing data.
vpn_client.startVpn(data, TunnelFd)
})
} catch (error) {
console.info("vpn setUp fail " + JSON.stringify(error));
}
}
// 5. Destroy the VPN.
Destroy() {
vpn_client.stopVpn(TunnelFd)
VpnConnection.destroy().then(function () {
console.info("vpn Destroy Success.")
}).catch(function (err) {
console.info("vpn Destroy Failed " + JSON.stringify(err))
})
}
build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
.onClick(() => {
console.info("vpn Client")
})
Button('CreateTunnel').onClick(() => {
this.CreateTunnel()
}).fontSize(50)
Button('Protect').onClick(() => {
this.Protect()
}).fontSize(50)
Button('SetupVpn').onClick(() => {
this.SetupVpn()
}).fontSize(50)
Button('Destroy').onClick(() => {
this.Destroy()
}).fontSize(50)
}
.width('100%')
}
.height('100%')
}
}
```
## C++ Code
The C++ code is used for underlying service implementation, such as UDP tunnel client implementation and vNIC data read and write.
```c++
#include "napi/native_api.h"
#include "hilog/log.h"
#include <cstring>
#include <thread>
#include <js_native_api.h>
#include <js_native_api_types.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <thread>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define BUFFER_SIZE 2048
#define VPN_LOG_TAG "NetMgrVpn"
#define VPN_LOG_DOMAIN 0x15b0
#define MAKE_FILE_NAME (strrchr(__FILE__, '/') + 1)
#define NETMANAGER_VPN_LOGE(fmt, ...) \
OH_LOG_Print(LOG_APP, LOG_ERROR, VPN_LOG_DOMAIN, VPN_LOG_TAG, "vpn [%{public}s %{public}d] " fmt, MAKE_FILE_NAME, \
__LINE__, ##__VA_ARGS__)
#define NETMANAGER_VPN_LOGI(fmt, ...) \
OH_LOG_Print(LOG_APP, LOG_INFO, VPN_LOG_DOMAIN, VPN_LOG_TAG, "vpn [%{public}s %{public}d] " fmt, MAKE_FILE_NAME, \
__LINE__, ##__VA_ARGS__)
#define NETMANAGER_VPN_LOGD(fmt, ...) \
OH_LOG_Print(LOG_APP, LOG_DEBUG, VPN_LOG_DOMAIN, VPN_LOG_TAG, "vpn [%{public}s %{public}d] " fmt, MAKE_FILE_NAME, \
__LINE__, ##__VA_ARGS__)
struct FdInfo {
int32_t tunFd = 0;
int32_t tunnelFd = 0;
struct sockaddr_in serverAddr;
};
static FdInfo fdInfo;
static bool threadRunF = false;
static std::thread threadt1;
static std::thread threadt2;
// Obtain the IP address of the UDP server.
static constexpr const int MAX_STRING_LENGTH = 1024;
std::string GetStringFromValueUtf8(napi_env env, napi_value value) {
std::string result;
char str[MAX_STRING_LENGTH] = {0};
size_t length = 0;
napi_get_value_string_utf8(env, value, str, MAX_STRING_LENGTH, &length);
if (length > 0) {
return result.append(str, length);
}
return result;
}
void HandleReadTunfd(FdInfo fdInfo) {
uint8_t buffer[BUFFER_SIZE] = {0};
while (threadRunF) {
int ret = read(fdInfo.tunFd, buffer, sizeof(buffer));
if (ret <= 0) {
if (errno != 11) {
NETMANAGER_VPN_LOGE("read tun device error: %{public}d, tunfd: %{public}d", errno, fdInfo.tunFd);
}
continue;
}
// Read data from the vNIC and send the data to the UDP server through the UDP tunnel.
NETMANAGER_VPN_LOGD("buffer: %{public}s, len: %{public}d", buffer, ret);
ret = sendto(fdInfo.tunnelFd, buffer, ret, 0, (struct sockaddr *)&fdInfo.serverAddr, sizeof(fdInfo.serverAddr));
if (ret <= 0) {
NETMANAGER_VPN_LOGE("send to server[%{public}s:%{public}d] failed, ret: %{public}d, error: %{public}s",
inet_ntoa(fdInfo.serverAddr.sin_addr), ntohs(fdInfo.serverAddr.sin_port), ret,
strerror(errno));
continue;
}
}
}
void HandleTcpReceived(FdInfo fdInfo) {
int addrlen = sizeof(struct sockaddr_in);
uint8_t buffer[BUFFER_SIZE] = {0};
while (threadRunF) {
int length = recvfrom(fdInfo.tunnelFd, buffer, sizeof(buffer), 0, (struct sockaddr *)&fdInfo.serverAddr,
(socklen_t *)&addrlen);
if (length < 0) {
if (errno != 11) {
NETMANAGER_VPN_LOGE("read tun device error: %{public}d, tunnelfd: %{public}d", errno, fdInfo.tunnelFd);
}
continue;
}
// Receive data from the UDP server and write the data to the vNIC.
NETMANAGER_VPN_LOGD("from [%{public}s:%{public}d] data: %{public}s, len: %{public}d",
inet_ntoa(fdInfo.serverAddr.sin_addr), ntohs(fdInfo.serverAddr.sin_port), buffer, length);
int ret = write(fdInfo.tunFd, buffer, length);
if (ret <= 0) {
NETMANAGER_VPN_LOGE("error Write To Tunfd, errno: %{public}d", errno);
}
}
}
static napi_value UdpConnect(napi_env env, napi_callback_info info) {
size_t argc = 2;
napi_value args[2] = {nullptr};
napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
int32_t port = 0;
napi_get_value_int32(env, args[1], &port);
std::string ipAddr = GetStringFromValueUtf8(env, args[0]);
NETMANAGER_VPN_LOGI("ip: %{public}s port: %{public}d", ipAddr.c_str(), port);
// Establish a UDP tunnel.
int32_t sockFd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockFd == -1) {
NETMANAGER_VPN_LOGE("socket() error");
return 0;
}
struct timeval timeout = {1, 0};
setsockopt(sockFd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(struct timeval));
memset(&fdInfo.serverAddr, 0, sizeof(fdInfo.serverAddr));
fdInfo.serverAddr.sin_family = AF_INET;
fdInfo.serverAddr.sin_addr.s_addr = inet_addr(ipAddr.c_str()); // server's IP addr
fdInfo.serverAddr.sin_port = htons(port); // port
NETMANAGER_VPN_LOGI("Connection successful");
napi_value tunnelFd;
napi_create_int32(env, sockFd, &tunnelFd);
return tunnelFd;
}
static napi_value StartVpn(napi_env env, napi_callback_info info) {
size_t argc = 2;
napi_value args[2] = {nullptr};
napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
napi_get_value_int32(env, args[0], &fdInfo.tunFd);
napi_get_value_int32(env, args[1], &fdInfo.tunnelFd);
if (threadRunF) {
threadRunF = false;
threadt1.join();
threadt2.join();
}
// Start two threads. One is used to read data from the vNIC, and the other is used to receive data from the server.
threadRunF = true;
std::thread tt1(HandleReadTunfd, fdInfo);
std::thread tt2(HandleTcpReceived, fdInfo);
threadt1 = std::move(tt1);
threadt2 = std::move(tt2);
NETMANAGER_VPN_LOGI("StartVpn successful");
napi_value retValue;
napi_create_int32(env, 0, &retValue);
return retValue;
}
static napi_value StopVpn(napi_env env, napi_callback_info info) {
size_t argc = 1;
napi_value args[1] = {nullptr};
napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
int32_t tunnelFd;
napi_get_value_int32(env, args[0], &tunnelFd);
if (tunnelFd) {
close(tunnelFd);
tunnelFd = 0;
}
// Stop the two threads.
if (threadRunF) {
threadRunF = false;
threadt1.join();
threadt2.join();
}
NETMANAGER_VPN_LOGI("StopVpn successful");
napi_value retValue;
napi_create_int32(env, 0, &retValue);
return retValue;
}
EXTERN_C_START
static napi_value Init(napi_env env, napi_value exports) {
napi_property_descriptor desc[] = {
{"udpConnect", nullptr, UdpConnect, nullptr, nullptr, nullptr, napi_default, nullptr},
{"startVpn", nullptr, StartVpn, nullptr, nullptr, nullptr, napi_default, nullptr},
{"stopVpn", nullptr, StopVpn, nullptr, nullptr, nullptr, napi_default, nullptr},
};
napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
return exports;
}
EXTERN_C_END
static napi_module demoModule = {
.nm_version = 1,
.nm_flags = 0,
.nm_filename = nullptr,
.nm_register_func = Init,
.nm_modname = "entry",
.nm_priv = ((void *)0),
.reserved = {0},
};
extern "C" __attribute__((constructor)) void RegisterEntryModule(void) {
napi_module_register(&demoModule);
}
```
# Socket Connection # Socket Connection
## Introduction ## Overview
The Socket Connection module allows an application to transmit data over a socket connection through the TCP, UDP, or TLS protocol. The Socket Connection module allows an application to transmit data over a socket connection through the TCP, UDP, or TLS protocol.
......
# Subscribing to State Changes of a Remote Object # Subscribing to State Changes of a Remote Object
## Overview
IPC/RPC allows you to subscribe to the state changes of a remote stub object. When the remote stub object dies, a death notification will be sent to your local proxy object. Such subscription and unsubscription are controlled by APIs. To be specific, you need to implement the **DeathRecipient** interface and the **onRemoteDied** API to clear resources. This callback is invoked when the process accommodating the remote stub object dies, or the device accommodating the remote stub object leaves the network. It is worth noting that these APIs should be called in the following order: The proxy object must first subscribe to death notifications of the stub object. If the stub object is in the normal state, the proxy object can cancel the subscription as required. If the process of the stub object exits or the device hosting the stub object goes offline, subsequent operations customized by the proxy object will be automatically triggered. IPC/RPC allows you to subscribe to the state changes of a remote stub object. When the remote stub object dies, a death notification will be sent to your local proxy object. Such subscription and unsubscription are controlled by APIs. To be specific, you need to implement the **DeathRecipient** interface and the **onRemoteDied** API to clear resources. This callback is invoked when the process accommodating the remote stub object dies, or the device accommodating the remote stub object leaves the network. It is worth noting that these APIs should be called in the following order: The proxy object must first subscribe to death notifications of the stub object. If the stub object is in the normal state, the proxy object can cancel the subscription as required. If the process of the stub object exits or the device hosting the stub object goes offline, subsequent operations customized by the proxy object will be automatically triggered.
## When to Use ## When to Use
......
# WebSocket Connection # WebSocket Connection
## When to Use ## Overview
You can use WebSocket to establish a bidirectional connection between a server and a client. Before doing this, you need to use the **createWebSocket()** API to create a **WebSocket** object and then use the **connect()** API to connect to the server. If the connection is successful, the client will receive a callback of the **open** event. Then, the client can communicate with the server using the **send()** API. When the server sends a message to the client, the client will receive a callback of the **message** event. If the client no longer needs this connection, it can call the **close()** API to disconnect from the server. Then, the client will receive a callback of the **close** event. You can use WebSocket to establish a bidirectional connection between a server and a client. Before doing this, you need to use the **createWebSocket()** API to create a **WebSocket** object and then use the **connect()** API to connect to the server. If the connection is successful, the client will receive a callback of the **open** event. Then, the client can communicate with the server using the **send()** API. When the server sends a message to the client, the client will receive a callback of the **message** event. If the client no longer needs this connection, it can call the **close()** API to disconnect from the server. Then, the client will receive a callback of the **close** event.
......
...@@ -68,7 +68,7 @@ The following table lists the APIs used for persisting user preference data. For ...@@ -68,7 +68,7 @@ The following table lists the APIs used for persisting user preference data. For
return; return;
} }
console.info('Succeeded in getting preferences.'); console.info('Succeeded in getting preferences.');
// Perform related data operations. // Before performing related data operations, obtain a Preferences instance.
}) })
} catch (err) { } catch (err) {
console.error(`Failed to get preferences. Code:${err.code},message:${err.message}`); console.error(`Failed to get preferences. Code:${err.code},message:${err.message}`);
...@@ -93,7 +93,7 @@ The following table lists the APIs used for persisting user preference data. For ...@@ -93,7 +93,7 @@ The following table lists the APIs used for persisting user preference data. For
return; return;
} }
console.info('Succeeded in getting preferences.'); console.info('Succeeded in getting preferences.');
// Perform related data operations. // Before performing related data operations, obtain a Preferences instance.
}) })
} catch (err) { } catch (err) {
console.error(`Failed to get preferences. Code is ${err.code},message:${err.message}`); console.error(`Failed to get preferences. Code is ${err.code},message:${err.message}`);
...@@ -220,4 +220,4 @@ The following table lists the APIs used for persisting user preference data. For ...@@ -220,4 +220,4 @@ The following table lists the APIs used for persisting user preference data. For
} catch (err) { } catch (err) {
console.error(`Failed to delete preferences. Code:${err.code}, message:${err.message}`); console.error(`Failed to delete preferences. Code:${err.code}, message:${err.message}`);
} }
``` ```
\ No newline at end of file
...@@ -171,7 +171,7 @@ The following uses a single KV store as an example to describe how to implement ...@@ -171,7 +171,7 @@ The following uses a single KV store as an example to describe how to implement
return; return;
} }
console.info('Succeeded in getting KVStore.'); console.info('Succeeded in getting KVStore.');
// Perform related data operations. // Before performing related data operations, obtain a KV store instance.
}); });
} catch (e) { } catch (e) {
console.error(`An unexpected error occurred. Code:${e.code},message:${e.message}`); console.error(`An unexpected error occurred. Code:${e.code},message:${e.message}`);
...@@ -275,4 +275,4 @@ The following uses a single KV store as an example to describe how to implement ...@@ -275,4 +275,4 @@ The following uses a single KV store as an example to describe how to implement
} }
} }
}); });
``` ```
\ No newline at end of file
# DFX # DFX
- [Development of Application Event Logging](hiappevent-guidelines.md) - [Development of Application Event Logging](hiappevent-guidelines.md)
- [Development of Performance Tracing](hitracemeter-guidelines.md)
- [Development of Distributed Call Chain Tracing](hitracechain-guidelines.md) - [Development of Distributed Call Chain Tracing](hitracechain-guidelines.md)
- [HiLog Development (Native)](hilog-guidelines.md) - [HiLog Development (Native)](hilog-guidelines.md)
- Performance Tracing - Performance Tracing
......
# Application Freeze (appfreeze) Log Analysis # Application Freeze (appfreeze) Log Analysis
## Introduction ## Overview
Application freeze (appfreeze) means that an application does not respond to user operations (for example, clicking) within a given period of time. OpenHarmony provides a mechanism for detecting appfreeze faults and generates appfreeze logs for fault analysis. Application freeze (appfreeze) means that an application does not respond to user operations (for example, clicking) within a given period of time. OpenHarmony provides a mechanism for detecting appfreeze faults and generates appfreeze logs for fault analysis.
......
# Application Recovery Development # Application Recovery Development
## When to Use ## Overview
During application running, some unexpected behaviors are inevitable. For example, unprocessed exceptions and errors are thrown, and the call or running constraints of the recovery framework are violated. During application running, some unexpected behaviors are inevitable. For example, unprocessed exceptions and errors are thrown, and the call or running constraints of the recovery framework are violated.
...@@ -99,9 +99,12 @@ import AbilityConstant from '@ohos.app.ability.AbilityConstant' ...@@ -99,9 +99,12 @@ import AbilityConstant from '@ohos.app.ability.AbilityConstant'
- Define and register the [ErrorObserver](../reference/apis/js-apis-inner-application-errorObserver.md) callback. For details about its usage, see [errorManager](../reference/apis/js-apis-app-ability-errorManager.md). - Define and register the [ErrorObserver](../reference/apis/js-apis-inner-application-errorObserver.md) callback. For details about its usage, see [errorManager](../reference/apis/js-apis-app-ability-errorManager.md).
```ts ```ts
var registerId = -1; export let abilityWant : Want // file1
var callback = {
onUnhandledException(errMsg) { import * as G form "../file1"
let registerId = -1;
let callback: Callback = {
onUnhandledException(errMsg: string): void {
console.log(errMsg); console.log(errMsg);
appRecovery.saveAppState(); appRecovery.saveAppState();
appRecovery.restartApp(); appRecovery.restartApp();
...@@ -112,7 +115,7 @@ import AbilityConstant from '@ohos.app.ability.AbilityConstant' ...@@ -112,7 +115,7 @@ import AbilityConstant from '@ohos.app.ability.AbilityConstant'
// Main window is created, set main page for this ability // Main window is created, set main page for this ability
console.log("[Demo] MainAbility onWindowStageCreate") console.log("[Demo] MainAbility onWindowStageCreate")
globalThis.registerObserver = (() => { G.registerObserver = (() => {
registerId = errorManager.on('error', callback); registerId = errorManager.on('error', callback);
}) })
...@@ -138,13 +141,16 @@ After the callback triggers **appRecovery.saveAppState()**, **onSaveState(state, ...@@ -138,13 +141,16 @@ After the callback triggers **appRecovery.saveAppState()**, **onSaveState(state,
After the callback triggers **appRecovery.restartApp()**, the application is restarted. After the restart, **onCreate(want, launchParam)** of **MainAbility** is called, and the saved data is in **parameters** of **want**. After the callback triggers **appRecovery.restartApp()**, the application is restarted. After the restart, **onCreate(want, launchParam)** of **MainAbility** is called, and the saved data is in **parameters** of **want**.
```ts ```ts
export let abilityWant : Want // file1
import * as GlobalWant form "../file1"
storage: LocalStorage storage: LocalStorage
onCreate(want, launchParam) { onCreate(want, launchParam) {
console.log("[Demo] MainAbility onCreate") console.log("[Demo] MainAbility onCreate")
globalThis.abilityWant = want; GlobalWant.abilityWant = want;
if (launchParam.launchReason == AbilityConstant.LaunchReason.APP_RECOVERY) { if (launchParam.launchReason == AbilityConstant.LaunchReason.APP_RECOVERY) {
this.storage = new LocalStorage(); this.storage = new LocalStorage();
let recoveryData = want.parameters["myData"]; let recoveryData: string = want.parameters["myData"];
this.storage.setOrCreate("myData", recoveryData); this.storage.setOrCreate("myData", recoveryData);
this.context.restoreWindowStage(this.storage); this.context.restoreWindowStage(this.storage);
} }
...@@ -154,12 +160,15 @@ onCreate(want, launchParam) { ...@@ -154,12 +160,15 @@ onCreate(want, launchParam) {
- Unregister the **ErrorObserver** callback. - Unregister the **ErrorObserver** callback.
```ts ```ts
export let abilityWant : Want // file1
import * as G form "../file1"
onWindowStageDestroy() { onWindowStageDestroy() {
// Main window is destroyed, release UI related resources // Main window is destroyed, release UI related resources
console.log("[Demo] MainAbility onWindowStageDestroy") console.log("[Demo] MainAbility onWindowStageDestroy")
globalThis.unRegisterObserver = (() => { G.unRegisterObserver = (() => {
errorManager.off('error', registerId, (err) => { errorManager.off(type: 'error', registerId: number, (err:Error) => {
console.error("[Demo] err:", err); console.error("[Demo] err:", err);
}); });
}) })
...@@ -171,20 +180,22 @@ onWindowStageDestroy() { ...@@ -171,20 +180,22 @@ onWindowStageDestroy() {
This is triggered by the recovery framework. You do not need to register an **ErrorObserver** callback. You only need to implement **onSaveState** for application state saving and **onCreate** for data restore. This is triggered by the recovery framework. You do not need to register an **ErrorObserver** callback. You only need to implement **onSaveState** for application state saving and **onCreate** for data restore.
```ts ```ts
export let abilityWant : Want // file1
import * as GlobalWant form "../file1"
export default class MainAbility extends Ability { export default class MainAbility extends Ability {
storage: LocalStorage onCreate(want: Want, launchParam:AbilityConstant.LaunchParam):void {
onCreate(want, launchParam) {
console.log("[Demo] MainAbility onCreate") console.log("[Demo] MainAbility onCreate")
globalThis.abilityWant = want; GlobalWant.abilityWant = want;
if (launchParam.launchReason == AbilityConstant.LaunchReason.APP_RECOVERY) { if (launchParam.launchReason == AbilityConstant.LaunchReason.APP_RECOVERY) {
this.storage = new LocalStorage(); this.storage = new LocalStorage();
let recoveryData = want.parameters["myData"]; let recoveryData: string = want.parameters["myData"];
this.storage.setOrCreate("myData", recoveryData); this.storage.setOrCreate<string>("myData", recoveryData);
this.context.restoreWindowStage(this.storage); this.context.restoreWindowStage(this.storage);
} }
} }
onSaveState(state, wantParams) { onSaveState(state: AbilityConstant.StateType, wantParams: { [key: string]: Object }) : AbilityConstant.OnSaveResult{
// Ability has called to save app data // Ability has called to save app data
console.log("[Demo] MainAbility onSaveState") console.log("[Demo] MainAbility onSaveState")
wantParams["myData"] = "my1234567"; wantParams["myData"] = "my1234567";
......
# cppcrash Log Analysis # Process Crash (cppcrash) Log Analysis
## Introduction ## Overview
A process crash refers to a C/C++ runtime crash. The FaultLogger module of OpenHarmony provides capabilities such as process crash detection, log collection, log storage, and log reporting, helping you to locate faults more effectively. A process crash refers to a C/C++ runtime crash. The FaultLogger module of OpenHarmony provides capabilities such as process crash detection, log collection, log storage, and log reporting, helping you to locate faults more effectively.
...@@ -23,7 +23,7 @@ Process crash detection is implemented based on the Linux signal mechanism. Curr ...@@ -23,7 +23,7 @@ Process crash detection is implemented based on the Linux signal mechanism. Curr
## Crash Log Collection ## Crash Log Collection
Process crash log is the fault log managed together with the app freeze and JS application crash logs by the FaultLogger module. You can collect process crash logs in any of the following ways: Process crash log is a type of fault logs managed together with the app freeze and JS application crash logs by the FaultLogger module. You can collect process crash logs in any of the following ways:
### Collecting Logs by Using Shell ### Collecting Logs by Using Shell
...@@ -72,17 +72,14 @@ Thread name:crasher <- Abnormal thread ...@@ -72,17 +72,14 @@ Thread name:crasher <- Abnormal thread
### Locating Faults Through Logs ### Locating Faults Through Logs
1. Determine the faulty module and fault type based on fault logs. - Determine the faulty module and fault type based on fault logs.
Generally, you can identify the faulty module based on the crash process name and identify the crash cause based on the signal. Besides, you can restore the function call chain of the crash stack based on the method name in the stack.
In the example, **SIGSEGV** is thrown by the Linux kernel because of access to an invalid memory address. The problem occurs in the **TriggerSegmentFaultException** function.
In most scenarios, a crash is caused by the top layer of the crash stack, such as null pointer access and proactive program abort.
Generally, you can identify the faulty module based on the crash process name and identify the crash cause based on the signal. Besides, you can restore the function call chain of the crash stack based on the method name in the stack.\
In the example, **SIGSEGV** is thrown by the Linux kernel because of access to an invalid memory address. The problem occurs in the **TriggerSegmentFaultException** function.\
In most scenarios, a crash is caused by the top layer of the crash stack, such as null pointer access and proactive program abort.\
If the cause cannot be located through the call stack, you need to check for other faults, for example, memory corruption or stack overflow. If the cause cannot be located through the call stack, you need to check for other faults, for example, memory corruption or stack overflow.
2. Use the addr2line tool of Linux to parse the code line number to restore the call stack at the time of process crash. - Use the addr2line tool of Linux to parse the code line number to restore the call stack at the time of process crash.
When using the addr2line tool to parse the code line number of the crash stack, make sure that binary files with debugging information is used. Generally, such files are generated during version build or application build. When using the addr2line tool to parse the code line number of the crash stack, make sure that binary files with debugging information is used. Generally, such files are generated during version build or application build.
...@@ -94,17 +91,17 @@ Thread name:crasher <- Abnormal thread ...@@ -94,17 +91,17 @@ Thread name:crasher <- Abnormal thread
\code root directory\out\product\exe.unstripped \code root directory\out\product\exe.unstripped
``` ```
You can run `apt-get install addr2line` to install the addr2line tool on Linux. You can run `apt-get install addr2line` to install the addr2line tool on Linux.\
On On DevEco Studio, you can also use the llvm-addr2line tool archived in the SDK to parse code line numbers. The usage method is the same. On On DevEco Studio, you can also use the llvm-addr2line tool archived in the SDK to parse code line numbers. The usage method is the same.
The following example shows how to use the addr2line tool to parse the code line number based on the offset address: The following example shows how to use the addr2line tool to parse the code line number based on the offset address.
**[product name]** indicates the device name.
``` ```
root:~/OpenHarmony/out/rk3568/exe.unstripped/hiviewdfx/faultloggerd$ addr2line -e crasher 0000332c root:~/OpenHarmony/out/[product name]/exe.unstripped/hiviewdfx/faultloggerd$ addr2line -e crasher 0000332c
base/hiviewdfx/faultloggerd/tools/crasher/dfx_crasher.c:57 base/hiviewdfx/faultloggerd/tools/crasher/dfx_crasher.c:57
``` ```
In this example, the crash is caused by assignment of a value to an unwritable area. It is in code line 57 in the **dfx_crasher.c** file. You can modify it to avoid the crash. In this example, the crash is caused by assignment of a value to an unwritable area. It is in code line 57 in the **dfx_crasher.c** file. You can modify it to avoid the crash.\
If the obtained code line number is seemingly incorrect, you can fine-tune the address (for example, subtract the address by 1) or disable some compilation optimization items. It is known that the obtained code line number may be incorrect when Link Time Optimization (LTO) is enabled. If the obtained code line number is seemingly incorrect, you can fine-tune the address (for example, subtract the address by 1) or disable some compilation optimization items. It is known that the obtained code line number may be incorrect when Link Time Optimization (LTO) is enabled.
# Development of Error Manager # Development of Error Manager
## When to Use ## Overview
If coding specification issues or errors exist in the code of an application, the application may encounter unexpected errors, for example, uncaught exceptions or application lifecycle timeouts, while it is running. In such a case, the application may exit unexpectedly. Error logs, however, are usually stored on users' local storage, making it inconvenient to locate faults. With the APIs provided by the **errorManager** module, your application will be able to report related errors and logs to your service platform for fault locating before it exits. If coding specification issues or errors exist in the code of an application, the application may encounter unexpected errors, for example, uncaught exceptions or application lifecycle timeouts, while it is running. In such a case, the application may exit unexpectedly. Error logs, however, are usually stored on users' local storage, making it inconvenient to locate faults. With the APIs provided by the **errorManager** module, your application will be able to report related errors and logs to your service platform for fault locating before it exits.
......
# Development of Application Event Logging # Development of Application Event Logging
## Introduction ## Overview
A traditional log system aggregates log information generated by all applications running on the entire device, making it difficult to identify key information in the log. Therefore, an effective logging mechanism is needed to evaluate mission-critical information, for example, number of visits, number of daily active users, user operation habits, and key factors that affect application usage. A traditional log system aggregates log information generated by all applications running on the entire device, making it difficult to identify key information in the log. Therefore, an effective logging mechanism is needed to evaluate mission-critical information, for example, number of visits, number of daily active users, user operation habits, and key factors that affect application usage.
......
# HiLog Development (Native) # HiLog Development (Native)
## Introduction ## Overview
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.
......
# Development of Distributed Call Chain Tracing # Development of Distributed Call Chain Tracing
## Introduction ## Overview
The hiTraceChain module provides APIs to implement call chain tracing throughout a service process. This can help you quickly obtain the run log for the call chain of a specified service process and locate faults in inter-device, inter-process, or inter-thread communications. The hiTraceChain module provides APIs to implement call chain tracing throughout a service process. This can help you quickly obtain the run log for the call chain of a specified service process and locate faults in inter-device, inter-process, or inter-thread communications.
......
# Development of Performance Tracing (ArkTS) # Development of Performance Tracing (ArkTS)
## Introduction ## Overview
hiTraceMeter provides APIs for system performance tracing. You can call the APIs provided by the hiTraceMeter module in your own service logic to effectively track service processes and check the system performance. hiTraceMeter provides APIs for system performance tracing. You can call the APIs provided by the hiTraceMeter module in your own service logic to effectively track service processes and check the system performance.
...@@ -21,7 +21,7 @@ hiTraceMeter provides APIs for system performance tracing. You can call the APIs ...@@ -21,7 +21,7 @@ hiTraceMeter provides APIs for system performance tracing. You can call the APIs
## Available APIs ## Available APIs
The performance tracing APIs are provided by the **hiTraceMeter** module. For details, see [API Reference](../reference/apis/js-apis-hitracemeter.md). The performance tracing APIs are provided by the **hiTraceMeter** module. For details, see [API Reference]( ../reference/apis/js-apis-hitracemeter.md).
**APIs for performance tracing** **APIs for performance tracing**
...@@ -35,60 +35,16 @@ The performance tracing APIs are provided by the **hiTraceMeter** module. For de ...@@ -35,60 +35,16 @@ The performance tracing APIs are provided by the **hiTraceMeter** module. For de
In this example, distributed call chain tracing begins when the application startup execution page is loaded and stops when the service usage is completed. In this example, distributed call chain tracing begins when the application startup execution page is loaded and stops when the service usage is completed.
1. Create a JS application project. In the displayed **Project** window, choose **entry** > **src** > **main** > **js** > **default** > **pages** > **index**, and double-click **index.js**. Add the code to implement performance tracing upon page loading. The sample code is as follows: 1. Create an ArkTS application project. In the displayed **Project** window, choose **entry** > **src** > **main** > **ets** > **pages** > **index**, and double-click **index.js**. Add the code to implement performance tracing upon page loading. For example, if the name of the trace task is **HITRACE\_TAG\_APP**, the sample code is as follows:
```js
import hiTraceMeter from '@ohos.hiTraceMeter'
export default {
data: {
title: ""
},
onInit() {
this.title = this.$t('strings.world');
// Start trace tasks with the same name concurrently.
hiTraceMeter.startTrace("business", 1);
// Keep the service process running.
console.log(`business running`);
hiTraceMeter.startTrace("business", 2); // Start the second trace task with the same name while the first task is still running. The tasks are running concurrently and therefore their taskId must be different.
// Keep the service process running.
console.log(`business running`);
hiTraceMeter.finishTrace("business", 1);
// Keep the service process running.
console.log(`business running`);
hiTraceMeter.finishTrace("business", 2);
// Start trace tasks with the same name in serial mode.
hiTraceMeter.startTrace("business", 1);
// Keep the service process running.
console.log(`business running`);
hiTraceMeter.finishTrace("business", 1); // End the first trace task.
// Keep the service process running.
console.log(`business running`);
hiTraceMeter.startTrace("business", 1); // Start the second trace task with the same name in serial mode.
// Keep the service process running.
console.log(`business running`);
let traceCount = 3;
hiTraceMeter.traceByValue("myTestCount", traceCount);
traceCount = 4;
hiTraceMeter.traceByValue("myTestCount", traceCount);
hiTraceMeter.finishTrace("business", 1);
}
}
```
2. Create an ArkTs application project. In the displayed **Project** window, choose **entry** > **src** > **main** > **ets** > **pages** > **index**, and double-click **index.js**. Add the code to implement performance tracing upon page loading. For example, if the name of the trace task is **HITRACE\_TAG\_APP**, the sample code is as follows:
```ts ```ts
import hitrace from '@ohos.hiTraceMeter'; import hitrace from '@ohos.hiTraceMeter';
@Entry @Entry
@Component @Component
struct Index { struct Index {
@State message: string = 'Hello World'; @State message: string = 'Hello World';
build() { build() {
Row() { Row() {
Column() { Column() {
...@@ -97,7 +53,7 @@ In this example, distributed call chain tracing begins when the application star ...@@ -97,7 +53,7 @@ In this example, distributed call chain tracing begins when the application star
.fontWeight(FontWeight.Bold) .fontWeight(FontWeight.Bold)
.onClick(() => { .onClick(() => {
this.message = 'Hello ArkUI'; this.message = 'Hello ArkUI';
// Start trace tasks with the same name concurrently. // Start trace tasks with the same name concurrently.
hitrace.startTrace("HITRACE_TAG_APP", 1001); hitrace.startTrace("HITRACE_TAG_APP", 1001);
// Keep the service process running. // Keep the service process running.
...@@ -107,7 +63,7 @@ In this example, distributed call chain tracing begins when the application star ...@@ -107,7 +63,7 @@ In this example, distributed call chain tracing begins when the application star
hitrace.startTrace("HITRACE_TAG_APP", 1002); hitrace.startTrace("HITRACE_TAG_APP", 1002);
// Keep the service process running. // Keep the service process running.
console.log(`HITRACE_TAG_APP running`); console.log(`HITRACE_TAG_APP running`);
hitrace.finishTrace("HITRACE_TAG_APP", 1001); hitrace.finishTrace("HITRACE_TAG_APP", 1001);
hitrace.finishTrace("HITRACE_TAG_APP", 1002); hitrace.finishTrace("HITRACE_TAG_APP", 1002);
...@@ -143,7 +99,7 @@ In this example, distributed call chain tracing begins when the application star ...@@ -143,7 +99,7 @@ In this example, distributed call chain tracing begins when the application star
``` ```
3. Click the run button on the application page. Then, run the following commands in sequence in shell: 3. Click the run button on the application page. Then, run the following commands in sequence in shell:
```shell ```shell
hdc shell hdc shell
hitrace --trace_begin app hitrace --trace_begin app
......
# Development of Performance Tracing (Native) # Development of Performance Tracing (Native)
## Introduction ## Overview
hiTraceMeter provides APIs for system performance tracing. You can call the APIs provided by the hiTraceMeter module in your own service logic to effectively track service processes and check the system performance. hiTraceMeter provides APIs for system performance tracing. You can call the APIs provided by the hiTraceMeter module in your own service logic to effectively track service processes and check the system performance.
> **NOTE** > **NOTE**
......
...@@ -36,10 +36,11 @@ You can use [attribute animation](../reference/arkui-ts/ts-animatorproperty.md) ...@@ -36,10 +36,11 @@ You can use [attribute animation](../reference/arkui-ts/ts-animatorproperty.md)
Applicable to: OpenHarmony 3.2 Beta 5 (API version 9) Applicable to: OpenHarmony 3.2 Beta 5 (API version 9)
**Solution** **Solution**
- Add **focusable\(true\)** to the list item to enable it to obtain focus. Use either of the following:
- 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. - 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? ## Why is the click event not triggered for the focused component upon the press of the Enter key after keyboard navigation?
...@@ -139,6 +140,8 @@ Currently, the menu is displayed when the bound component is clicked or long pre ...@@ -139,6 +140,8 @@ Currently, the menu is displayed when the bound component is clicked or long pre
Applicable to: OpenHarmony 3.2 Beta5 (API version 9) Applicable to: OpenHarmony 3.2 Beta5 (API version 9)
**Solution**
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. 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? ## How do I implement the slide up and slide down effect for page transition?
...@@ -199,7 +202,7 @@ Applicable to: OpenHarmony 3.2 Beta5 (API version 9) ...@@ -199,7 +202,7 @@ Applicable to: OpenHarmony 3.2 Beta5 (API version 9)
**Symptom** **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. 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** **Solution**
...@@ -266,4 +269,4 @@ struct ComponentChild2 { ...@@ -266,4 +269,4 @@ struct ComponentChild2 {
**Reference** **Reference**
[Transition Animation Within the Component](../ui/arkts-enter-exit-transition.md) [Enter/Exit Transition](../ui/arkts-enter-exit-transition.md)
...@@ -21,42 +21,6 @@ try { ...@@ -21,42 +21,6 @@ try {
} }
``` ```
## How do I hide the status bar to get the immersive effect?
Applicable to: OpenHarmony 3.2 Beta5 (API version 9)
**Solution**
1. Use **onWindowStageCreate** to obtain a **windowClass** object.
```
onWindowStageCreate(windowStage) {
// When the main window is created, set the main page for this ability.
console.log("[Demo] MainAbility onWindowStageCreate")
windowStage.getMainWindow((err, data) => {
if (err.code) {
console.error('Failed to obtain the main window.')
return;
}
// Obtain a windowClass object.
globalThis.windowClass = data;
})
}
```
2. Enable the full-screen mode for the window and hide the status bar.
```
globalThis.windowClass.setFullScreen(isFullScreen, (err, data) => {
if (err.code) {
console.error('Failed to enable the full-screen mode. Cause:' + JSON.stringify(err));
return;
}
console.info('Succeeded in enabling the full-screen mode. Data: ' + JSON.stringify(data));
});
```
## How do I obtain the window width and height? ## How do I obtain the window width and height?
Applicable to: OpenHarmony 3.2 Beta5 (API version 9, stage model) Applicable to: OpenHarmony 3.2 Beta5 (API version 9, stage model)
......
...@@ -18,3 +18,6 @@ ...@@ -18,3 +18,6 @@
- [Purgeable Memory Development](purgeable-memory-guidelines.md) - [Purgeable Memory Development](purgeable-memory-guidelines.md)
- Device Management - Device Management
- [USB DDK Development](usb-ddk-guidelines.md) - [USB DDK Development](usb-ddk-guidelines.md)
- Data Management
- [RelationalStore Development](native-relational-store-guidelines.md)
...@@ -26,6 +26,13 @@ For details about the APIs, see [native_buffer](../reference/native-apis/_o_h___ ...@@ -26,6 +26,13 @@ For details about the APIs, see [native_buffer](../reference/native-apis/_o_h___
The following describes how to use the native APIs provided by **NativeBuffer** to create an **OH_NativeBuffer** instance, obtain memory properties, and map the corresponding ION memory to the process address space. The following describes how to use the native APIs provided by **NativeBuffer** to create an **OH_NativeBuffer** instance, obtain memory properties, and map the corresponding ION memory to the process address space.
**Adding Dynamic Link Libraries**
Add the following library to **CMakeLists.txt**:
```txt
libnative_buffer.so
```
**Header File** **Header File**
```c++ ```c++
#include <native_buffer/native_buffer.h> #include <native_buffer/native_buffer.h>
...@@ -51,14 +58,14 @@ The following describes how to use the native APIs provided by **NativeBuffer** ...@@ -51,14 +58,14 @@ The following describes how to use the native APIs provided by **NativeBuffer**
if (ret != 0) { if (ret != 0) {
std::cout << "OH_NativeBuffer_Map Failed" << std::endl; std::cout << "OH_NativeBuffer_Map Failed" << std::endl;
} }
// Unmap the ION memory from the process address space when it is no longer needed. // Unmap the ION memory from the process address space when it is no longer needed.
ret = OH_NativeBuffer_Unmap(buffer); ret = OH_NativeBuffer_Unmap(buffer);
if (ret != 0) { if (ret != 0) {
std::cout << "OH_NativeBuffer_Unmap Failed" << std::endl; std::cout << "OH_NativeBuffer_Unmap Failed" << std::endl;
} }
``` ```
3. Obtain the memory properties. 3. Obtain the memory properties.
```c++ ```c++
// Obtain the properties of the OH_NativeBuffer instance. // Obtain the properties of the OH_NativeBuffer instance.
......
...@@ -27,6 +27,17 @@ For details about the APIs, see [native_image](../reference/native-apis/_o_h___n ...@@ -27,6 +27,17 @@ For details about the APIs, see [native_image](../reference/native-apis/_o_h___n
The following steps describe how to use the native APIs provided by **NativeImage** to create an **OH_NativeImage** instance as the consumer and update the data to a OpenGL external texture. The following steps describe how to use the native APIs provided by **NativeImage** to create an **OH_NativeImage** instance as the consumer and update the data to a OpenGL external texture.
**Adding Dynamic Link Libraries**
Add the following libraries to **CMakeLists.txt**:
```txt
libEGL.so
libGLESv3.so
libnative_image.so
libnative_window.so
libnative_buffer.so
```
**Header File** **Header File**
```c++ ```c++
#include <EGL/egl.h> #include <EGL/egl.h>
...@@ -159,41 +170,48 @@ The following steps describe how to use the native APIs provided by **NativeImag ...@@ -159,41 +170,48 @@ The following steps describe how to use the native APIs provided by **NativeImag
4. Write the produced content to a **NativeWindowBuffer** instance. 4. Write the produced content to a **NativeWindowBuffer** instance.
1. Obtain a NativeWindowBuffer instance from the NativeWindow instance. 1. Obtain a NativeWindowBuffer instance from the NativeWindow instance.
```c++
OHNativeWindowBuffer* buffer = nullptr;
int fenceFd;
// Obtain a NativeWindowBuffer instance by calling OH_NativeWindow_NativeWindowRequestBuffer.
OH_NativeWindow_NativeWindowRequestBuffer(nativeWindow, &buffer, &fenceFd);
BufferHandle *handle = OH_NativeWindow_GetBufferHandleFromNative(buffer); ```c++
int code = SET_BUFFER_GEOMETRY; OHNativeWindowBuffer* buffer = nullptr;
int32_t width = 0x100; int fenceFd;
int32_t height = 0x100; // Obtain a NativeWindowBuffer instance by calling OH_NativeWindow_NativeWindowRequestBuffer.
ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, width, height); OH_NativeWindow_NativeWindowRequestBuffer(nativeWindow, &buffer, &fenceFd);
```
3. Write the produced content to the **NativeWindowBuffer** instance. BufferHandle *handle = OH_NativeWindow_GetBufferHandleFromNative(buffer);
```c++ int code = SET_BUFFER_GEOMETRY;
static uint32_t value = 0x00; int32_t width = 0x100;
value++; int32_t height = 0x100;
uint32_t *pixel = static_cast<uint32_t *>(handle->virAddr); ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, width, height);
for (uint32_t x = 0; x < width; x++) { ```
for (uint32_t y = 0; y < height; y++) {
*pixel++ = value; 2. Write the produced content to the **NativeWindowBuffer** instance.
}
} ```c++
``` static uint32_t value = 0x00;
4. Flush the **NativeWindowBuffer** to the **NativeWindow**. value++;
```c++ uint32_t *pixel = static_cast<uint32_t *>(handle->virAddr);
// Set the refresh region. If Rect in Region is a null pointer or rectNumber is 0, all contents in the NativeWindowBuffer are changed. for (uint32_t x = 0; x < width; x++) {
Region region{nullptr, 0}; for (uint32_t y = 0; y < height; y++) {
// Flush the buffer to the consumer through OH_NativeWindow_NativeWindowFlushBuffer, for example, by displaying it on the screen. *pixel++ = value;
OH_NativeWindow_NativeWindowFlushBuffer(nativeWindow, buffer, fenceFd, region); }
``` }
5. Destroy the **NativeWindow** instance when it is no longer needed. ```
```c++
OH_NativeWindow_DestroyNativeWindow(nativeWindow); 3. Flush the **NativeWindowBuffer** to the **NativeWindow**.
```
```c++
// Set the refresh region. If Rect in Region is a null pointer or rectNumber is 0, all contents in the NativeWindowBuffer are changed.
Region region{nullptr, 0};
// Flush the buffer to the consumer through OH_NativeWindow_NativeWindowFlushBuffer, for example, by displaying it on the screen.
OH_NativeWindow_NativeWindowFlushBuffer(nativeWindow, buffer, fenceFd, region);
```
4. Destroy the **NativeWindow** instance when it is no longer needed.
```c++
OH_NativeWindow_DestroyNativeWindow(nativeWindow);
```
5. Update the content to the OpenGL texture. 5. Update the content to the OpenGL texture.
```c++ ```c++
// Update the content to the OpenGL texture. // Update the content to the OpenGL texture.
......
# RelationalStore Development Guide
## When to Use
RelationalStore provides a complete mechanism for local database management. It offers a series of interfaces for adding, deleting, modifying, and querying data in an RDB store. To satisfy different needs in complicated scenarios, RelationalStore also supports direct execution of SQL statements.
## Basic concepts
- **OH_Predicates**: A representation of the property or feature of a data entity, or the relationship between data entities. It is used to define operation conditions.
- **OH_Cursor**: A set of query results, which allows access to the required data in flexible modes.
## Restrictions
- The default logging mode is Write Ahead Log (WAL), and the default flushing mode is **FULL** mode.
- RelationalStore supports a maximum of four connection pools to manage read and write operations.
- To ensure data accuracy, only one write operation is allowed at a time.
- Once an application is uninstalled, related database files and temporary files on the device are automatically deleted.
## Available APIs
For details about the APIs, see [RDB](../reference/native-apis/_r_d_b.md).
| API| Description|
| -------- | -------- |
| OH_Rdb_GetOrOpen(const OH_Rdb_Config *config, int *errCode) | Obtains an OH_Rdb_Store instance for RDB store operations.|
| OH_Rdb_Execute(OH_Rdb_Store *store, const char *sql) | Executes an SQL statement that contains specified arguments but returns no value.|
| OH_Rdb_Insert(OH_Rdb_Store *store, const char *table, OH_VBucket *valuesBucket) | Inserts a row of data into a table.|
| OH_Rdb_Update(OH_Rdb_Store *store, OH_VBucket *valuesBucket, OH_Predicates *predicates); | Updates data in the RDB store based on the specified OH_Predicates instance.|
| OH_Rdb_Delete(OH_Rdb_Store *store, OH_Predicates *predicates) | Deletes data from the RDB store based on the specified OH_Predicates instance.|
| OH_Rdb_Query(OH_Rdb_Store *store, OH_Predicates *predicates, const char *const *columnNames, int length) | Queries data in the RDB store based on specified conditions.|
| OH_Rdb_DeleteStore(const OH_Rdb_Config *config) | Deletes an RDB store.|
## How to Develop
1. Obtain the OH_Rdb_Store instance and create a database file.
Example:
```c
// Create an OH_Rdb_Config object.
OH_Rdb_Config config;
// The path is the application sandbox path.
config.dataBaseDir = "xxx";
// Database file name.
config.storeName = "RdbTest.db";
// Application bundle name.
config.bundleName = "xxx";
// Module name.
config.moduleName = "xxx";
// Security level of the database file.
config.securityLevel = OH_Rdb_SecurityLevel::S1;
// Whether the database is encrypted.
config.isEncrypt = false;
// Memory size occupied by config.
config.selfSize = sizeof(OH_Rdb_Config);
int errCode = 0;
// Obtain the OH_Rdb_Store instance.
OH_Rdb_Store *store_ = OH_Rdb_GetOrOpen(&config, &errCode);
```
2. After obtaining the OH_Rdb_Store instance, call **OH_Rdb_Execute** to create a table and call **OH_Rdb_Insert** to insert data to the table created.
Example:
```c
char createTableSql[] = "CREATE TABLE IF NOT EXISTS EMPLOYEE (ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT NOT NULL, "
"AGE INTEGER, SALARY REAL, CODES BLOB)";
// Create a table.
OH_Rdb_Execute(store_, createTableSql);
// Create a key-value pair instance.
OH_VBucket *valueBucket = OH_Rdb_CreateValuesBucket();
valueBucket->putText(valueBucket, "NAME", "Lisa");
valueBucket->putInt64(valueBucket, "AGE", 18);
valueBucket->putReal(valueBucket, "SALARY", 100.5);
uint8_t arr[] = {1, 2, 3, 4, 5};
int len = sizeof(arr) / sizeof(arr[0]);
valueBucket->putBlob(valueBucket, "CODES", arr, len);
// Insert data.
int rowId = OH_Rdb_Insert(store_, "EMPLOYEE", valueBucket);
// Destroy the KV pair instance.
valueBucket->destroy(valueBucket);
```
> **NOTE**
>
> **RelationalStore** does not provide explicit flush operations for data persistence. **insert()** stores data in a file persistently.
3. Modify or delete data based on the specified **Predicates** instance.
Call **OH_Rdb_Update** to modify data and call **OH_Rdb_Delete** to delete data.
Example:
```c
// Modify data.
OH_VBucket *valueBucket = OH_Rdb_CreateValuesBucket();
valueBucket->putText(valueBucket, "NAME", "Rose");
valueBucket->putInt64(valueBucket, "AGE", 22);
valueBucket->putReal(valueBucket, "SALARY", 200.5);
uint8_t arr[] = {1, 2, 3, 4, 5};
int len = sizeof(arr) / sizeof(arr[0]);
valueBucket->putBlob(valueBucket, "CODES", arr, len);
OH_Predicates *predicates = OH_Rdb_CreatePredicates("EMPLOYEE");
OH_VObject *valueObject = OH_Rdb_CreateValueObject();
const char *name = "Lisa";
valueObject->putText(valueObject, name);
predicates->equalTo(predicates, "NAME", valueObject)->andOperate(predicates);
uint32_t count = 1;
double salary = 100.5;
valueObject->putDouble(valueObject, &salary, count);
predicates->equalTo(predicates, "SALARY", valueObject);
int changeRows = OH_Rdb_Update(store_, valueBucket, predicates);
valueObject->destroy(valueObject);
valueBucket->destroy(valueBucket);
predicates->destroy(predicates);
```
```c
// Delete data.
OH_Predicates *predicates = OH_Rdb_CreatePredicates("EMPLOYEE");
OH_VObject *valueObject = OH_Rdb_CreateValueObject();
const char *name = "Lisa";
valueObject->putText(valueObject, name);
predicates->equalTo(predicates, "NAME", valueObject);
int deleteRows = OH_Rdb_Delete(store_, predicates);
valueObject->destroy(valueObject);
predicates->destroy(predicates);
```
4. Query data based on the conditions specified by **Predicates**.
Call **OH_Rdb_Query** to query data. The data obtained is returned in a **OH_Cursor** object.
Example:
```c
OH_Predicates *predicates = OH_Rdb_CreatePredicates("EMPLOYEE");
const char *columnNames[] = {"NAME", "AGE"};
int len = sizeof(columnNames) / sizeof(columnNames[0]);
OH_Cursor *cursor = OH_Rdb_Query(store_, predicates, columnNames, len);
int columnCount = 0;
cursor->getColumnCount(cursor, &columnCount);
// OH_Cursor is a cursor of a data set. By default, the cursor points to the -1st record. Valid data starts from 0.
int64_t age;
while (cursor->goToNextRow(cursor) == OH_Rdb_ErrCode::RDB_OK) {
cursor->getInt64(cursor, 1, &age);
}
// Destroy the Predicates instance.
predicates->destroy(predicates);
// Destroy the result set.
cursor->destroy(cursor);
```
5. Delete the database.
Call **OH_Rdb_DeleteStore** to delete an RDB store and related database files.
Example:
```c
// Close the database instance.
OH_Rdb_CloseStore(store_);
// Delete the database file.
OH_Rdb_DeleteStore(&config);
```
...@@ -6,12 +6,12 @@ The **NativeVSync** module is used to obtain virtual synchronization (VSync) sig ...@@ -6,12 +6,12 @@ The **NativeVSync** module is used to obtain virtual synchronization (VSync) sig
## Available APIs ## Available APIs
| API| Description:| | API| Description|
| -------- | -------- | | -------- | -------- |
| OH_NativeVSync_Create (const char \*name, unsigned int length) | Creates an **OH_NativeVSync** instance. A new **OH_NativeVSync** instance is created each time this function is called.| | OH_NativeVSync_Create (const char \*name, unsigned int length) | Creates an **OH_NativeVSync** instance. A new **OH_NativeVSync** instance is created each time this function is called.|
| OH_NativeVSync_Destroy (OH_NativeVSync \*nativeVsync) | Destroys an **OH_NativeVSync** instance.| | OH_NativeVSync_Destroy (OH_NativeVSync \*nativeVsync) | Destroys an **OH_NativeVSync** instance.|
| OH_NativeVSync_FrameCallback (long long timestamp, void \*data) | Sets a callback function. **timestamp** indicates the timestamp, and **data** indicates the input parameter of the callback function. | | OH_NativeVSync_FrameCallback (long long timestamp, void \*data) | Sets a callback function. **timestamp** indicates the timestamp, and **data** indicates the input parameter of the callback function.|
| OH_NativeVSync_RequestFrame (OH_NativeVSync \*nativeVsync, OH_NativeVSync_FrameCallback callback, void \*data) | Requests the next VSync signal. When the signal arrives, a callback function is invoked.| | OH_NativeVSync_RequestFrame (OH_NativeVSync \*nativeVsync, OH_NativeVSync_FrameCallback callback, void \*data) | Requests the next VSync signal. When the signal arrives, a callback function is invoked.|
For details about the APIs, see [native_vsync](../reference/native-apis/_native_vsync.md). For details about the APIs, see [native_vsync](../reference/native-apis/_native_vsync.md).
...@@ -19,6 +19,13 @@ For details about the APIs, see [native_vsync](../reference/native-apis/_native_ ...@@ -19,6 +19,13 @@ For details about the APIs, see [native_vsync](../reference/native-apis/_native_
The following steps describe how to use the native APIs provided by **NativeVSync** to create and destroy an **OH_NativeVSync** instance and set the VSync callback function. The following steps describe how to use the native APIs provided by **NativeVSync** to create and destroy an **OH_NativeVSync** instance and set the VSync callback function.
**Adding Dynamic Link Libraries**
Add the following library to **CMakeLists.txt**:
```txt
libnative_vsync.so
```
**Header File** **Header File**
```c++ ```c++
#include <native_vsync/native_vsync.h> #include <native_vsync/native_vsync.h>
...@@ -33,12 +40,12 @@ The following steps describe how to use the native APIs provided by **NativeVSyn ...@@ -33,12 +40,12 @@ The following steps describe how to use the native APIs provided by **NativeVSyn
std::cout << "OnVSync: " << timestamp << std::endl; std::cout << "OnVSync: " << timestamp << std::endl;
} }
OH_NativeVSync_FrameCallback callback = OnVSync; // The callback function must be of the OH_NativeVSync_FrameCallback type. OH_NativeVSync_FrameCallback callback = OnVSync; // The callback function must be of the OH_NativeVSync_FrameCallback type.
``` ```
2. Create an **OH_NativeVSync** instance. 2. Create an **OH_NativeVSync** instance.
```c++ ```c++
char name[] = "hello_vsync"; char name[] = "hello_vsync";
OH_NativeVSync* nativeVSync = OH_NativeVSync_Create(name, strlen(name)); OH_NativeVSync* nativeVSync = OH_NativeVSync_Create(name, strlen(name));
``` ```
3. Set the VSync callback function through the **OH_NativeVSync** instance. 3. Set the VSync callback function through the **OH_NativeVSync** instance.
```c++ ```c++
......
...@@ -11,11 +11,11 @@ The following scenarios are common for NativeWindow development: ...@@ -11,11 +11,11 @@ The following scenarios are common for NativeWindow development:
## Available APIs ## Available APIs
| API| Description| | API| Description|
| -------- | -------- | | -------- | -------- |
| OH_NativeWindow_NativeWindowRequestBuffer (OHNativeWindow \*window, OHNativeWindowBuffer \*\*buffer, int \*fenceFd) | Requests an **OHNativeWindowBuffer** through an **OHNativeWindow** instance for content production.| | OH_NativeWindow_NativeWindowRequestBuffer (OHNativeWindow \*window, OHNativeWindowBuffer \*\*buffer, int \*fenceFd) | Requests an **OHNativeWindowBuffer** through an **OHNativeWindow** instance for content production.|
| OH_NativeWindow_NativeWindowFlushBuffer (OHNativeWindow \*window, OHNativeWindowBuffer \*buffer, int fenceFd, Region region) | Flushes the **OHNativeWindowBuffer** filled with the content to the buffer queue through an **OHNativeWindow** instance for content consumption.| | OH_NativeWindow_NativeWindowFlushBuffer (OHNativeWindow \*window, OHNativeWindowBuffer \*buffer, int fenceFd, Region region) | Flushes the **OHNativeWindowBuffer** filled with the content to the buffer queue through an **OHNativeWindow** instance for content consumption.|
| OH_NativeWindow_NativeWindowHandleOpt (OHNativeWindow \*window, int code,...) | Sets or obtains the attributes of an **OHNativeWindow**, including the width, height, and content format.| | OH_NativeWindow_NativeWindowHandleOpt (OHNativeWindow \*window, int code,...) | Sets or obtains the attributes of an **OHNativeWindow**, including the width, height, and content format.|
For details about the APIs, see [native_window](../reference/native-apis/_native_window.md). For details about the APIs, see [native_window](../reference/native-apis/_native_window.md).
...@@ -37,7 +37,7 @@ libnative_window.so ...@@ -37,7 +37,7 @@ libnative_window.so
#include <native_window/external_window.h> #include <native_window/external_window.h>
``` ```
1. Obtain an **OHNativeWindow** instance. 1. Obtain an **OHNativeWindow** instance.
You can call the APIs provided by [OH_NativeXComponent_Callback](../reference/native-apis/_o_h___native_x_component___callback.md) to obtain an **OHNativeWindow** instance. An example code snippet is provided below. For details about how to use the **\<XComponent>**, see [XComponent Development](xcomponent-guidelines.md). You can call the APIs provided by [OH_NativeXComponent_Callback](../reference/native-apis/_o_h___native_x_component___callback.md) to obtain an **OHNativeWindow** instance. An example code snippet is provided below. For details about how to use the **\<XComponent>**, see [XComponent Development](xcomponent-guidelines.md).
1. Add an **\<XComponent>** to the .ets file. 1. Add an **\<XComponent>** to the .ets file.
...@@ -159,5 +159,3 @@ libnative_window.so ...@@ -159,5 +159,3 @@ libnative_window.so
// munmap failed // munmap failed
} }
``` ```
<!--no_check-->
\ No newline at end of file
# Connecting the Neural Network Runtime to an AI Inference Framework # Development Guide for Connecting the Neural Network Runtime to an AI Inference Framework
## When to Use ## When to Use
...@@ -19,8 +19,7 @@ The environment requirements for the Neural Network Runtime are as follows: ...@@ -19,8 +19,7 @@ The environment requirements for the Neural Network Runtime are as follows:
- Development environment: Ubuntu 18.04 or later. - Development environment: Ubuntu 18.04 or later.
- Access device: a standard device running OpenHarmony. The built-in hardware accelerator driver has been connected to the Neural Network Runtime through an HDI API. - Access device: a standard device running OpenHarmony. The built-in hardware accelerator driver has been connected to the Neural Network Runtime through an HDI API.
The Neural Network Runtime is opened to external systems through OpenHarmony Native APIs. Therefore, you need to use the Native development suite of the OpenHarmony to compile Neural Network Runtime applications. The Neural Network Runtime is opened to external systems through OpenHarmony Native APIs. Therefore, you need to use the Native development suite of the OpenHarmony to compile Neural Network Runtime applications.
### Environment Setup ### Environment Setup
...@@ -33,7 +32,6 @@ unzip native-linux-{version number}.zip ...@@ -33,7 +32,6 @@ unzip native-linux-{version number}.zip
``` ```
The directory structure after decompression is as follows. The content in the directory may vary depending on version iteration. Use the Native APIs of the latest version. The directory structure after decompression is as follows. The content in the directory may vary depending on version iteration. Use the Native APIs of the latest version.
```text ```text
native/ native/
─ ─ build // Cross-compilation toolchain ─ ─ build // Cross-compilation toolchain
...@@ -488,4 +486,4 @@ The development process of the Neural Network Runtime consists of three phases: ...@@ -488,4 +486,4 @@ The development process of the Neural Network Runtime consists of three phases:
```shell ```shell
rm /data/local/tmp/*nncache rm /data/local/tmp/*nncache
``` ```
\ No newline at end of file
...@@ -18,6 +18,15 @@ For details about the APIs, see [Vulkan](../reference/native-lib/third_party_vul ...@@ -18,6 +18,15 @@ For details about the APIs, see [Vulkan](../reference/native-lib/third_party_vul
The following steps illustrate how to create a **VkSurfaceKHR** instance. The following steps illustrate how to create a **VkSurfaceKHR** instance.
**Adding Dynamic Link Libraries**
Add the following libraries to **CMakeLists.txt**:
```txt
libace_ndk.z.so
libnative_window.so
libvulkan.so
```
**Header File** **Header File**
```c++ ```c++
#include <ace/xcomponent/native_interface_xcomponent.h> #include <ace/xcomponent/native_interface_xcomponent.h>
......
...@@ -23,8 +23,7 @@ Selected state attributes of AppStorage can be synced with different data source ...@@ -23,8 +23,7 @@ Selected state attributes of AppStorage can be synced with different data source
As mentioned above, if you want to establish a binding between AppStorage and a custom component, you'll need the \@StorageProp and \@StorageLink decorators. Use \@StorageProp(key) or \@StorageLink(key) to decorate variables in the component, where **key** identifies the attribute in AppStorage. As mentioned above, if you want to establish a binding between AppStorage and a custom component, you'll need the \@StorageProp and \@StorageLink decorators. Use \@StorageProp(key) or \@StorageLink(key) to decorate variables in the component, where **key** identifies the attribute in AppStorage.
When a custom component is initialized, the \@StorageProp(key)/\@StorageLink(key) decorated variable is initialized with the value of the attribute with the given key in AppStorage. Local initialization is mandatory. If an attribute with the given key is missing from AppStorage, it will be added with the stated initializing value. (Whether the attribute with the given key exists in AppStorage depends on the application logic.) When a custom component is initialized, the \@StorageProp(key)/\@StorageLink(key) decorated variable is initialized with the value of the attribute with the given key in AppStorage. Whether the attribute with the given key exists in AppStorage depends on the application logic. This means that the attribute with the given key may be missing from AppStorage. In light of this, local initialization is mandatory for the \@StorageProp(key)/\@StorageLink(key) decorated variable.
By decorating a variable with \@StorageProp(key), a one-way data synchronization is established with the attribute with the given key in AppStorage. A local change can be made, but it will not be synchronized to AppStorage. An update to the attribute with the given key in AppStorage will overwrite local changes. By decorating a variable with \@StorageProp(key), a one-way data synchronization is established with the attribute with the given key in AppStorage. A local change can be made, but it will not be synchronized to AppStorage. An update to the attribute with the given key in AppStorage will overwrite local changes.
...@@ -193,9 +192,85 @@ struct CompA { ...@@ -193,9 +192,85 @@ struct CompA {
} }
``` ```
### Persistent Subscription and Callback ### Unrecommended: Using @StorageLink to Implement Event Notification
Compared with the common mechanism for event notification, the two-way synchronization mechanism of @StorageLink and AppStorage is far less cost efficient and therefore not recommended. This is because AppStorage stores UI-related data, and its changes will cause costly UI refresh.
In the following example, any tap event in the **TapImage** component will trigger a change of the **tapIndex** attribute. As @StorageLink establishes a two-way data synchronization with AppStorage, the local change is synchronized to AppStorage. As a result, all visible custom components owning the **tapIndex** attribute bound to AppStorage are notified to refresh the UI.
```ts
// xxx.ets
class ViewData {
title: string;
uri: Resource;
color: Color = Color.Black;
constructor(title: string, uri: Resource) {
this.title = title;
this.uri = uri
}
}
@Entry
@Component
struct Gallery2 {
dataList: Array<ViewData> = [new ViewData('flower', $r('app.media.icon')), new ViewData('OMG', $r('app.media.icon')), new ViewData('OMG', $r('app.media.icon'))]
scroller: Scroller = new Scroller()
build() {
Column() {
Grid(this.scroller) {
ForEach(this.dataList, (item: ViewData, index?: number) => {
GridItem() {
TapImage({
uri: item.uri,
index: index
})
}.aspectRatio(1)
}, (item: ViewData, index?: number) => {
return JSON.stringify(item) + index;
})
}.columnsTemplate('1fr 1fr')
}
}
}
@Component
export struct TapImage {
@StorageLink('tapIndex') @Watch('onTapIndexChange') tapIndex: number = -1;
@State tapColor: Color = Color.Black;
private index: number;
private uri: Resource;
// Check whether the component is selected.
onTapIndexChange() {
if (this.tapIndex >= 0 && this.index === this.tapIndex) {
console.info(`tapindex: ${this.tapIndex}, index: ${this.index}, red`)
this.tapColor = Color.Red;
} else {
console.info(`tapindex: ${this.tapIndex}, index: ${this.index}, black`)
this.tapColor = Color.Black;
}
}
The persistent subscription and callback can help reduce overhead and enhance code readability. build() {
Column() {
Image(this.uri)
.objectFit(ImageFit.Cover)
.onClick(() => {
this.tapIndex = this.index;
})
.border({ width: 5, style: BorderStyle.Dotted, color: this.tapColor })
}
}
}
```
To implement event notification with less overhead and higher code readability, use **emit** instead, with which you can subscribe to an event and receive event callback.
```ts ```ts
...@@ -294,10 +369,9 @@ export struct TapImage { ...@@ -294,10 +369,9 @@ export struct TapImage {
} }
``` ```
The following example uses the message mechanism to subscribe to events. Because this mechanism can result in a large number of nodes to listen for and a long implementation time, it is not recommended. The preceding notification logic is simple. It can be simplified into a ternary expression as follows:
```ts ```
// xxx.ets // xxx.ets
class ViewData { class ViewData {
title: string; title: string;
...@@ -338,22 +412,11 @@ struct Gallery2 { ...@@ -338,22 +412,11 @@ struct Gallery2 {
@Component @Component
export struct TapImage { export struct TapImage {
@StorageLink('tapIndex') @Watch('onTapIndexChange') tapIndex: number = -1; @StorageLink('tapIndex') tapIndex: number = -1;
@State tapColor: Color = Color.Black; @State tapColor: Color = Color.Black;
private index: number; private index: number;
private uri: Resource; private uri: Resource;
// Check whether the component is selected.
onTapIndexChange() {
if (this.tapIndex >= 0 && this.index === this.tapIndex) {
console.info(`tapindex: ${this.tapIndex}, index: ${this.index}, red`)
this.tapColor = Color.Red;
} else {
console.info(`tapindex: ${this.tapIndex}, index: ${this.index}, black`)
this.tapColor = Color.Black;
}
}
build() { build() {
Column() { Column() {
Image(this.uri) Image(this.uri)
...@@ -361,14 +424,18 @@ export struct TapImage { ...@@ -361,14 +424,18 @@ export struct TapImage {
.onClick(() => { .onClick(() => {
this.tapIndex = this.index; this.tapIndex = this.index;
}) })
.border({ width: 5, style: BorderStyle.Dotted, color: this.tapColor }) .border({
width: 5,
style: BorderStyle.Dotted,
color: (this.tapIndex >= 0 && this.index === this.tapIndex) ? Color.Red : Color.Black
})
} }
} }
} }
``` ```
## Restrictions ## Restrictions
When using AppStorage together with [PersistentStorage](arkts-persiststorage.md) and [Environment](arkts-environment.md), pay attention to the following: When using AppStorage together with [PersistentStorage](arkts-persiststorage.md) and [Environment](arkts-environment.md), pay attention to the following:
...@@ -377,5 +444,5 @@ When using AppStorage together with [PersistentStorage](arkts-persiststorage.md) ...@@ -377,5 +444,5 @@ When using AppStorage together with [PersistentStorage](arkts-persiststorage.md)
- A call to **Environment.EnvProp()** after creating the attribute in AppStorage will fail. This is because AppStorage already has an attribute with the same name, and the environment variable will not be written into AppStorage. Therefore, you are advised not to use the preset environment variable name in AppStorage. - A call to **Environment.EnvProp()** after creating the attribute in AppStorage will fail. This is because AppStorage already has an attribute with the same name, and the environment variable will not be written into AppStorage. Therefore, you are advised not to use the preset environment variable name in AppStorage.
- Changes to the variables decorated by state decorators will cause UI re-render. If the changes are for message communication, rather than for UI re-render, the emitter mode is recommended. For the example, see [Persistent Subscription and Callback](#persistent-subscription-and-callback). - Changes to the variables decorated by state decorators will cause UI re-render. If the changes are for message communication, rather than for UI re-render, the emitter mode is recommended. For the example, see [Unrecommended: Using @StorageLink to Implement Event Notification](#unrecommended-using-storagelink-to-implement-event-notification).
<!--no_check--> <!--no_check-->
...@@ -21,14 +21,14 @@ Syntax: ...@@ -21,14 +21,14 @@ Syntax:
```ts ```ts
@Builder myBuilderFunction({ ... }) @Builder MyBuilderFunction({ ... })
``` ```
Usage: Usage:
```ts ```ts
this.myBuilderFunction({ ... }) this.MyBuilderFunction({ ... })
``` ```
- Defining one or more custom builder (\@Builder decorated) functions inside a custom component is allowed. Such a custom builder function can be considered as a private, special type of member functions of that component. - Defining one or more custom builder (\@Builder decorated) functions inside a custom component is allowed. Such a custom builder function can be considered as a private, special type of member functions of that component.
...@@ -66,7 +66,7 @@ There are two types of parameter passing for custom builder functions: [by-value ...@@ -66,7 +66,7 @@ There are two types of parameter passing for custom builder functions: [by-value
- The parameter type must be the same as the declared parameter type. The **undefined** or **null** constants as well as expressions evaluating to these values are not allowed. - The parameter type must be the same as the declared parameter type. The **undefined** or **null** constants as well as expressions evaluating to these values are not allowed.
- All parameters are immutable inside the custom builder function. If mutability and synchronization of the mutation is required, the custom builder should be replaced by a custom component with a [@Link](arkts-link.md) decorated variable. - All parameters are immutable inside the@Builder decorated function.
- The \@Builder function body follows the same [syntax rules](arkts-create-custom-components.md#build-function) as the **build** function. - The \@Builder function body follows the same [syntax rules](arkts-create-custom-components.md#build-function) as the **build** function.
......
...@@ -70,8 +70,6 @@ To fully understand the preceding example, a knowledge of the following concepts ...@@ -70,8 +70,6 @@ To fully understand the preceding example, a knowledge of the following concepts
- [Universal Style of a Custom Component](#universal-style-of-a-custom-component) - [Universal Style of a Custom Component](#universal-style-of-a-custom-component)
- [Custom Attribute Methods](#custom-attribute-methods)
## Basic Structure of a Custom Component ## Basic Structure of a Custom Component
...@@ -106,6 +104,8 @@ To fully understand the preceding example, a knowledge of the following concepts ...@@ -106,6 +104,8 @@ To fully understand the preceding example, a knowledge of the following concepts
> **NOTE** > **NOTE**
> >
> Since API version 9, this decorator is supported in ArkTS widgets. > Since API version 9, this decorator is supported in ArkTS widgets.
>
> Since API version 10, the \@Entry decorator accepts an optional parameter of type [LocalStorage](arkts-localstorage.md) or type [EntryOptions](#entryoptions10).
```ts ```ts
@Entry @Entry
...@@ -114,6 +114,23 @@ To fully understand the preceding example, a knowledge of the following concepts ...@@ -114,6 +114,23 @@ To fully understand the preceding example, a knowledge of the following concepts
} }
``` ```
### EntryOptions<sup>10+</sup>
Describes the named route options.
| Name | Type | Mandatory| Description |
| ------ | ------ | ---- | ------------------------------------------------------------ |
| routeName | string | No| Name of the target named route.|
| storage | [LocalStorage](arkts-localstorage.md) | No| Storage of page-level UI state.|
```ts
@Entry({ routeName : 'myPage' })
@Component
struct MyComponent {
}
```
- \@Recycle: A custom component decorated with \@Recycle can be reused. - \@Recycle: A custom component decorated with \@Recycle can be reused.
> **NOTE** > **NOTE**
...@@ -328,68 +345,4 @@ struct MyComponent { ...@@ -328,68 +345,4 @@ struct MyComponent {
> >
> When ArkUI sets styles for custom components, an invisible container component is set for **MyComponent2**. These styles are set on the container component instead of the **\<Button>** component of **MyComponent2**. As seen from the rendering result, the red background color is not directly applied to the button. Instead, it is applied to the container component that is invisible to users where the button is located. > When ArkUI sets styles for custom components, an invisible container component is set for **MyComponent2**. These styles are set on the container component instead of the **\<Button>** component of **MyComponent2**. As seen from the rendering result, the red background color is not directly applied to the button. Instead, it is applied to the container component that is invisible to users where the button is located.
## Custom Attribute Methods
Custom components do not support custom attribute methods. You can use the Controller capability to implement custom APIs.
```ts
// Custom controller
export class MyComponentController {
item: MyComponent = null;
setItem(item: MyComponent) {
this.item = item;
}
changeText(value: string) {
this.item.value = value;
}
}
// Custom component
@Component
export default struct MyComponent {
public controller: MyComponentController = null;
@State value: string = 'Hello World';
build() {
Column() {
Text(this.value)
.fontSize(50)
}
}
aboutToAppear() {
if (this.controller)
this.controller.setItem (this); // Link to the controller.
}
}
// Processing logic
@Entry
@Component
struct StyleExample {
controller = new MyComponentController();
build() {
Column() {
MyComponent({ controller: this.controller })
}
.onClick(() => {
this.controller.changeText('Text');
})
}
}
```
In the preceding example:
1. The **aboutToAppear** method of the **MyComponent** child component passes the current **this** pointer to the **item** member variable of **MyComponentController**.
2. The **StyleExample** parent component holds a **Controller** instance and with which calls the **changeText** API of **Controller**. That is, the value of the state variable **value** of **MyComponent** is changed through the **this** pointer of the **MyComponent** child component held by the controller.
Through the encapsulation of the controller, **MyComponent** exposes the **changeText** API. All instances that hold the controller can call the **changeText** API to change the value of the **MyComponent** state variable **value**.
<!--no_check--> <!--no_check-->
...@@ -15,12 +15,11 @@ Environment is a singleton object created by the ArkUI framework at application ...@@ -15,12 +15,11 @@ Environment is a singleton object created by the ArkUI framework at application
- Use **Environment.EnvProp** to save the environment variables of the device to AppStorage. - Use **Environment.EnvProp** to save the environment variables of the device to AppStorage.
```ts ```ts
// Save the language code of the device to AppStorage. The default value is en. // Save languageCode to AppStorage. The default value is en.
// Whenever its value changes in the device environment, it will update its value in AppStorage.
Environment.EnvProp('languageCode', 'en'); Environment.EnvProp('languageCode', 'en');
``` ```
- To keep a component variable updated with changes in the device environment, this variable should be decorated with \@StorageProp. - Decorate the variables with \@StorageProp to link them with components.
```ts ```ts
@StorageProp('languageCode') lang : string = 'en'; @StorageProp('languageCode') lang : string = 'en';
...@@ -29,6 +28,7 @@ Environment is a singleton object created by the ArkUI framework at application ...@@ -29,6 +28,7 @@ Environment is a singleton object created by the ArkUI framework at application
The chain of updates is as follows: Environment > AppStorage > Component. The chain of updates is as follows: Environment > AppStorage > Component.
> **NOTE** > **NOTE**
>
> An \@StorageProp decorated variable can be locally modified, but the change will not be updated to AppStorage. This is because the environment variable parameters are read-only to the application. > An \@StorageProp decorated variable can be locally modified, but the change will not be updated to AppStorage. This is because the environment variable parameters are read-only to the application.
...@@ -69,3 +69,29 @@ if (lang.get() === 'en') { ...@@ -69,3 +69,29 @@ if (lang.get() === 'en') {
console.info('Hello!'); console.info('Hello!');
} }
``` ```
## Restrictions
Environment can be called only when the [UIContext](../reference/apis/js-apis-arkui-UIContext.md#uicontext), which can be obtained through [runScopedTask](../reference/apis/js-apis-arkui-UIContext.md#runscopedtask), is specified. If Environment is called otherwise, no device environment data can be obtained.
```ts
// EntryAbility.ts
import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';
export default class EntryAbility extends UIAbility {
onWindowStageCreate(windowStage: window.WindowStage) {
windowStage.loadContent('pages/Index');
let window = windowStage.getMainWindow()
window.then(window => {
let uicontext = window.getUIContext()
uicontext.runScopedTask(() => {
Environment.EnvProp('languageCode', 'en');
})
})
}
}
```
...@@ -36,7 +36,7 @@ LocalStorage provides two decorators based on the synchronization type of the co ...@@ -36,7 +36,7 @@ LocalStorage provides two decorators based on the synchronization type of the co
## Restrictions ## Restrictions
- Once created, the type of a named attribute cannot be changed. Subsequent calls to **Set** must set a value of same type. - Once created, the type of a named attribute cannot be changed. Subsequent calls to **Set** must set a value of same type.
- LocalStorage provides page-level storage. The [GetShared](../reference/arkui-ts/ts-state-management.md#getshared9) API can only obtain the LocalStorage instance transferred through [windowStage.loadContent](../reference/apis/js-apis-window.md#loadcontent9) in the current stage. Otherwise, **undefined** is returned. Example: [Sharing a LocalStorage Instance from UIAbility to One or More Pages](#sharing-a-localstorage-instance-from-uiability-to-one-or-more-pages). - LocalStorage provides page-level storage. The [GetShared](../reference/arkui-ts/ts-state-management.md#getshared10) API can only obtain the LocalStorage instance passed through [windowStage.loadContent](../reference/apis/js-apis-window.md#loadcontent9) in the current stage. If the instance is not available, **undefined** is returned. For the example, see [Example of Sharing a LocalStorage Instance from UIAbility to One or More Pages](#example-of-sharing-a-localstorage-instance-from-uiability-to-one-or-more-pages).
## \@LocalStorageProp ## \@LocalStorageProp
...@@ -300,9 +300,9 @@ struct CompA { ...@@ -300,9 +300,9 @@ struct CompA {
``` ```
### State Variable Synchronization Between Sibling Nodes ### Example of Syncing State Variable Between Sibling Components
This example shows how to use \@LocalStorageLink to create a two-way synchronization for the state between sibling nodes. This example shows how to use \@LocalStorageLink to create a two-way synchronization for the state between sibling components.
Check the changes in the **Parent** custom component. Check the changes in the **Parent** custom component.
...@@ -377,7 +377,7 @@ Changes in the **Child** custom component: ...@@ -377,7 +377,7 @@ Changes in the **Child** custom component:
``` ```
### Sharing a LocalStorage Instance from UIAbility to One or More Pages ### Example of Sharing a LocalStorage Instance from UIAbility to One or More Pages
In the preceding examples, the LocalStorage instance is shared only in an \@Entry decorated component and its owning child component (a page). To enable a LocalStorage instance to be shared across pages, you can create a LocalStorage instance in the owning UIAbility and call windowStage.[loadContent](../reference/apis/js-apis-window.md#loadcontent9). In the preceding examples, the LocalStorage instance is shared only in an \@Entry decorated component and its owning child component (a page). To enable a LocalStorage instance to be shared across pages, you can create a LocalStorage instance in the owning UIAbility and call windowStage.[loadContent](../reference/apis/js-apis-window.md#loadcontent9).
......
...@@ -162,6 +162,26 @@ class ClassB { ...@@ -162,6 +162,26 @@ class ClassB {
this.a = a; this.a = a;
} }
} }
@Observed
class ClassD {
public c: ClassC;
constructor(c: ClassC) {
this.c = c;
}
}
@Observed
class ClassC extends ClassA {
public k: number;
constructor(k: number) {
// Invoke the parent class method to process k.
super(k);
this.k = k;
}
}
``` ```
...@@ -169,60 +189,64 @@ class ClassB { ...@@ -169,60 +189,64 @@ class ClassB {
```ts ```ts
@Component @Component
struct ViewA { struct ViewC {
label: string = 'ViewA1'; label: string = 'ViewC1';
@ObjectLink a: ClassA; @ObjectLink c: ClassC;
build() { build() {
Row() { Row() {
Button(`ViewA [${this.label}] this.a.c=${this.a.c} +1`) Column() {
.onClick(() => { Text(`ViewC [${this.label}] this.a.c = ${this.c.c}`)
this.a.c += 1; .fontColor('#ffffffff')
}) .backgroundColor('#ff3fc4c4')
} .height(50)
.borderRadius(25)
Button(`ViewC: this.c.c add 1`)
.backgroundColor('#ff7fcf58')
.onClick(() => {
this.c.c += 1;
console.log('this.c.c:' + this.c.c)
})
}
.width(300)
} }
} }
}
@Entry @Entry
@Component @Component
struct ViewB { struct ViewB {
@State b: ClassB = new ClassB(new ClassA(0)); @State b: ClassB = new ClassB(new ClassA(0));
@State child : ClassD = new ClassD(new ClassC(0));
build() { build() {
Column() { Column() {
ViewA({ label: 'ViewA #1', a: this.b.a }) ViewC({ label: 'ViewC #3', c: this.child.c})
ViewA({ label: 'ViewA #2', a: this.b.a }) Button(`ViewC: this.child.c.c add 10`)
.backgroundColor('#ff7fcf58')
Button(`ViewB: this.b.a.c+= 1`)
.onClick(() => {
this.b.a.c += 1;
})
Button(`ViewB: this.b.a = new ClassA(0)`)
.onClick(() => { .onClick(() => {
this.b.a = new ClassA(0); this.child.c.c += 10
}) console.log('this.child.c.c:' + this.child.c.c)
Button(`ViewB: this.b = new ClassB(ClassA(0))`)
.onClick(() => {
this.b = new ClassB(new ClassA(0));
}) })
} }
} }
} }
``` ```
The @Observed decorated **ClassC** class can observe changes in attributes inherited from the base class.
Event handlers in **ViewB**: Event handlers in **ViewB**:
- this.b.a = new ClassA(0) and this.b = new ClassB(new ClassA(0)): Change to the \@State decorated variable **b** and its attributes. - this.child.c = new ClassA(0) and this.b = new ClassB(new ClassA(0)): Change to the \@State decorated variable **b** and its attributes.
- this.b.a.c = ... : Change at the second layer. Though [@State](arkts-state.md#observed-changes) cannot observe the change at the second layer, the change of an attribute of \@Observed decorated ClassA, which is attribute **c** in this example, can be observed by \@ObjectLink. - this.child.c.c = ... : Change at the second layer. Though [@State](arkts-state.md#observed-changes) cannot observe the change at the second layer, the change of an attribute of \@Observed decorated ClassA, which is attribute **c** in this example, can be observed by \@ObjectLink.
Event handlers in **ViewA**: Event handle in **ViewC**:
- this.a.c += 1: Changes to the \@ObjectLink decorated variable cause the button label to be updated. Unlike \@Prop, \@ObjectLink does not have a copy of its source. Instead, \@ObjectLink creates a reference to its source. - this.c.c += 1: Changes to the \@ObjectLink decorated variable **a** cause the button label to be updated. Unlike \@Prop, \@ObjectLink does not have a copy of its source. Instead, \@ObjectLink creates a reference to its source.
- The \@ObjectLink decorated variable is read-only. Assigning **this.a = new ClassA(...)** is not allowed. Once value assignment occurs, the reference to the data source is reset and the synchronization is interrupted. - The \@ObjectLink decorated variable is read-only. Assigning **this.a = new ClassA(...)** is not allowed. Once value assignment occurs, the reference to the data source is reset and the synchronization is interrupted.
...@@ -297,7 +321,7 @@ struct ViewB { ...@@ -297,7 +321,7 @@ struct ViewB {
2. ViewA({ label: ViewA this.arrA[first], a: this.arrA[0] }): The preceding update changes the first element in the array. Therefore, the **ViewA** component instance bound to **this.arrA[0]** is updated. 2. ViewA({ label: ViewA this.arrA[first], a: this.arrA[0] }): The preceding update changes the first element in the array. Therefore, the **ViewA** component instance bound to **this.arrA[0]** is updated.
- this.arrA.push(new ClassA(0)): The change of this state variable triggers two updates with different effects. - this.arrA.push(new ClassA(0)): The change of this state variable triggers two updates with different effects.
1. ForEach: The newly added Class A object is unknown to the **ForEach** [itemGenerator](arkts-rendering-control-foreach.md#api-description). The item builder of **ForEach** will be executed to create a **View A** component instance. 1. ForEach: The newly added **ClassA** object is unknown to the **ForEach** [itemGenerator](arkts-rendering-control-foreach.md#api-description). The item builder of **ForEach** will be executed to create a **ViewA** component instance.
2. ViewA({ label: ViewA this.arrA[last], a: this.arrA[this.arrA.length-1] }): The last item of the array is changed. As a result, the second **View A** component instance is changed. For **ViewA({ label: ViewA this.arrA[first], a: this.arrA[0] })**, a change to the array does not trigger a change to the array item, so the first **View A** component instance is not refreshed. 2. ViewA({ label: ViewA this.arrA[last], a: this.arrA[this.arrA.length-1] }): The last item of the array is changed. As a result, the second **View A** component instance is changed. For **ViewA({ label: ViewA this.arrA[first], a: this.arrA[0] })**, a change to the array does not trigger a change to the array item, so the first **View A** component instance is not refreshed.
- this.arrA[Math.floor (this.arrA.length/2)].c: [@State](arkts-state.md#observed-changes) cannot observe changes at the second layer. However, as **ClassA** is decorated by \@Observed, the change of its attributes will be observed by \@ObjectLink. - this.arrA[Math.floor (this.arrA.length/2)].c: [@State](arkts-state.md#observed-changes) cannot observe changes at the second layer. However, as **ClassA** is decorated by \@Observed, the change of its attributes will be observed by \@ObjectLink.
......
...@@ -24,7 +24,7 @@ Persistence of data is a relatively slow operation. Applications should avoid th ...@@ -24,7 +24,7 @@ Persistence of data is a relatively slow operation. Applications should avoid th
The preceding situations may overload the change process of persisted data. As a result, the PersistentStorage implementation may limit the change frequency of persisted attributes. The preceding situations may overload the change process of persisted data. As a result, the PersistentStorage implementation may limit the change frequency of persisted attributes.
PersistentStorage is associated with UIContext and can be called to persist data only when [UIContext](../reference/apis/js-apis-arkui-UIContext.md#uicontext) is specified. The context can be identified in [runScopedTask](../reference/apis/js-apis-arkui-UIContext.md#runscopedtask). PersistentStorage can be called to persist data only when the [UIContext](../reference/apis/js-apis-arkui-UIContext.md#uicontext), which can be obtained through [runScopedTask](../reference/apis/js-apis-arkui-UIContext.md#runscopedtask), is specified.
## Application Scenarios ## Application Scenarios
...@@ -92,7 +92,7 @@ struct Index { ...@@ -92,7 +92,7 @@ struct Index {
1. The state variable **\@StorageLink('aProp') aProp** is updated, triggering the **\<Text>** component to be re-rendered. 1. The state variable **\@StorageLink('aProp') aProp** is updated, triggering the **\<Text>** component to be re-rendered.
2. The two-way synchronization between the \@StorageLink decorated variable and AppStorage results in the change of the **\@StorageLink('aProp') aProp** being synchronized back to AppStorage. 2. The two-way synchronization between the \@StorageLink decorated variable and AppStorage results in the change of the **\@StorageLink('aProp') aProp** being synchronized back to AppStorage.
3. The change of the **aProp** attribute in AppStorage triggers any other one-way or two-way bound variables to be updated. (In this example, there are no such other variables.) 3. The change of the **aProp** attribute in AppStorage triggers any other one-way or two-way bound variables to be updated. (In this example, there are no such other variables.)
4. Because the attribute corresponding to **aProp** has been persisted, the change of the **aProp** attribute in AppStorage triggers PersistentStorage to write the attribute and its changed value to the device disk. 4. Because the attribute corresponding to **aProp** has been persisted, the change of the **aProp** attribute in AppStorage triggers PersistentStorage to write the attribute and its new value to the device disk.
- Subsequent application running: - Subsequent application running:
1. **PersistentStorage.PersistProp('aProp', 47)** is called. A search for the **aProp** attribute on the PersistentStorage disk succeeds. 1. **PersistentStorage.PersistProp('aProp', 47)** is called. A search for the **aProp** attribute on the PersistentStorage disk succeeds.
......
...@@ -528,11 +528,11 @@ struct MyComponent { ...@@ -528,11 +528,11 @@ struct MyComponent {
} }
Row() { Row() {
Button('Click to change locally !').width(480).height(60).margin({ top: 10 }) Button('Click to change locally !').width(180).height(60).margin({ top: 10 })
.onClick(() => { .onClick(() => {
this.customCounter2++ this.customCounter2++
}) })
}.height(100).width(480) }.height(100).width(180)
Row() { Row() {
Text(`Custom Local: ${this.customCounter2}`).width(90).height(40).fontColor('#FF0010') Text(`Custom Local: ${this.customCounter2}`).width(90).height(40).fontColor('#FF0010')
...@@ -563,7 +563,7 @@ struct MainProgram { ...@@ -563,7 +563,7 @@ struct MainProgram {
MyComponent({ customCounter: this.mainCounter }) MyComponent({ customCounter: this.mainCounter })
// customCounter2 of the child component can also be initialized from the parent component. The value from the parent component overwrites the locally assigned value of customCounter2 during initialization. // customCounter2 of the child component can also be initialized from the parent component. The value from the parent component overwrites the locally assigned value of customCounter2 during initialization.
MyComponent({ customCounter: this.mainCounter, customCounter2: this.mainCounter }) MyComponent({ customCounter: this.mainCounter, customCounter2: this.mainCounter })
}.width('40%') }
} }
} }
} }
......
...@@ -3,6 +3,9 @@ ...@@ -3,6 +3,9 @@
**ForEach** enables repeated content based on array-type data. **ForEach** enables repeated content based on array-type data.
> **NOTE**
>
> Since API version 9, this API is supported in ArkTS widgets.
## API Description ## API Description
...@@ -19,15 +22,15 @@ ForEach( ...@@ -19,15 +22,15 @@ ForEach(
| Name | Type | Mandatory | Description | | Name | Type | Mandatory | Description |
| ------------- | ---------------------------------------- | ---- | ---------------------------------------- | | ------------- | ---------------------------------------- | ---- | ---------------------------------------- |
| arr | Array | Yes | An array, which can be empty, in which case no child component is created. The functions that return array-type values are also allowed, for example, **arr.slice (1, 3)**. The set functions cannot change any state variables including the array itself, such as **Array.splice**, **Array.sort**, and **Array.reverse**.| | arr | Array | Yes | An array, which can be empty, in which case no child component is created. The functions that return array-type values are also allowed, for example, **arr.slice (1, 3)**. The set functions cannot change any state variables including the array itself, such as **Array.splice**, **Array.sort**, and **Array.reverse**.|
| itemGenerator | (item:&nbsp;any,&nbsp;index?:&nbsp;number)&nbsp;=&gt;&nbsp;void | Yes | A lambda function used to generate one or more child components for each data item in an array. Each component and its child component list must be contained in parentheses.<br>**NOTE**<br>- The type of the child component must be the one allowed inside the parent container component of **ForEach**. For example, a **\<LitemItem>** child component is allowed only when the parent container component of **ForEach** is **\<List>**.<br>- The child build function is allowed to return an **if** or another **ForEach**. **ForEach** can be placed inside **if**.<br>- The optional **index** parameter should only be specified in the function signature if used in its body.| | itemGenerator | (item: any, index?: number) =&gt; void | Yes | A lambda function used to generate one or more child components for each data item in an array. Each component and its child component list must be contained in parentheses.<br>**NOTE**<br>- The type of the child component must be the one allowed inside the parent container component of **ForEach**. For example, a **\<ListItem>** child component is allowed only when the parent container component of **ForEach** is **\<List>**.<br>- The child build function is allowed to return an **if** or another **ForEach**. **ForEach** can be placed inside **if**.<br>- The optional **index** parameter should only be specified in the function signature if used in its body.|
| keyGenerator | (item:&nbsp;any,&nbsp;index?:&nbsp;number)&nbsp;=&gt;&nbsp;string | No | An anonymous function used to generate a unique and fixed key value for each data item in an array. This key-value generator is optional. However, for performance reasons, it is strongly recommended that the key-value generator be provided, so that the development framework can better identify array changes. For example, if no key-value generator is provided, a reverse of an array will result in rebuilding of all nodes in **ForEach**.<br>**NOTE**<br>- Two items inside the same array must never work out the same ID.<br>- If **index** is not used, an item's ID must not change when the item's position within the array changes. However, if **index** is used, then the ID must change when the item is moved within the array.<br>- When an item is replaced by a new one (with a different value), the ID of the replaced and the ID of the new item must be different.<br>- When **index** is used in the build function, it should also be used in the ID generation function.<br>- The ID generation function is not allowed to mutate any component state.| | keyGenerator | (item: any, index?: number) =&gt; string | No | An anonymous function used to generate a unique and fixed key value for each data item in an array. This key-value generator is optional. However, for performance reasons, it is strongly recommended that the key-value generator be provided, so that the development framework can better identify array changes. For example, if no key-value generator is provided, a reverse of an array will result in rebuilding of all nodes in **ForEach**.<br>**NOTE**<br>- Two items inside the same array must never work out the same ID.<br>- If **index** is not used, an item's ID must not change when the item's position within the array changes. However, if **index** is used, then the ID must change when the item is moved within the array.<br>- When an item is replaced by a new one (with a different value), the ID of the replaced and the ID of the new item must be different.<br>- When **index** is used in the build function, it should also be used in the ID generation function.<br>- The ID generation function is not allowed to mutate any component state.|
## Restrictions ## Restrictions
- **ForEach** must be used in container components. - **ForEach** must be used in container components.
- The type of the child component must be the one allowed inside the parent container component of **ForEach**. - The type of the child component must be the one allowed inside the parent container component of **ForEach**.
- The **itemGenerator** function can contain an **if/else** statement, and an **if/else** statement can contain **ForEach**. - The **itemGenerator** function can contain an **if/else** statement, and an **if/else** statement can contain **ForEach**.
......
...@@ -34,8 +34,8 @@ interface DataChangeListener { ...@@ -34,8 +34,8 @@ interface DataChangeListener {
| Name | Type | Mandatory | Description | | Name | Type | Mandatory | Description |
| ------------- | --------------------------------------- | ---- | ---------------------------------------- | | ------------- | --------------------------------------- | ---- | ---------------------------------------- |
| dataSource | IDataSource | Yes | **LazyForEach** data source. You need to implement related APIs. | | dataSource | IDataSource | Yes | **LazyForEach** data source. You need to implement related APIs. |
| itemGenerator | (item:&nbsp;any)&nbsp;=&gt;&nbsp;void | Yes | Child component generation function, which generates a child component for each data item in the array.<br>**NOTE**<br>The function body of **itemGenerator** must be included in braces {...}. **itemGenerator** can and must generate only one child component for each iteration. The **if** statement is allowed in **itemGenerator**, but you must ensure that each branch of the **if** statement creates a child component of the same type. **ForEach** and **LazyForEach** statements are not allowed in **itemGenerator**.| | itemGenerator | (item: any) =&gt; void | Yes | Child component generation function, which generates a child component for each data item in the array.<br>**NOTE**<br>The function body of **itemGenerator** must be included in braces {...}. **itemGenerator** can and must generate only one child component for each iteration. The **if** statement is allowed in **itemGenerator**, but you must ensure that each branch of the **if** statement creates a child component of the same type. **ForEach** and **LazyForEach** statements are not allowed in **itemGenerator**.|
| keyGenerator | (item:&nbsp;any)&nbsp;=&gt;&nbsp;string | No | ID generation function, which generates a unique and fixed ID for each data item in the data source. This ID must remain unchanged for the data item even when the item is relocated in the array. When the item is replaced by a new item, the ID of the new item must be different from that of the replaced item. This ID generation function is optional. However, for performance reasons, it is strongly recommended that the ID generation function be provided, so that the framework can better identify array changes. For example, if no ID generation function is provided, a reverse of an array will result in rebuilding of all nodes in **LazyForEach**.<br>**NOTE**<br>The ID generated for each data item in the data source must be unique.| | keyGenerator | (item: any) =&gt; string | No | ID generation function, which generates a unique and fixed ID for each data item in the data source. This ID must remain unchanged for the data item even when the item is relocated in the array. When the item is replaced by a new item, the ID of the new item must be different from that of the replaced item. This ID generation function is optional. However, for performance reasons, it is strongly recommended that the ID generation function be provided, so that the framework can better identify array changes. For example, if no ID generation function is provided, a reverse of an array will result in rebuilding of all nodes in **LazyForEach**.<br>**NOTE**<br>The ID generated for each data item in the data source must be unique.|
## Description of IDataSource ## Description of IDataSource
...@@ -52,10 +52,10 @@ interface IDataSource { ...@@ -52,10 +52,10 @@ interface IDataSource {
| Declaration | Parameter Type | Description | | Declaration | Parameter Type | Description |
| ---------------------------------------- | ------------------ | ------------------------------------- | | ---------------------------------------- | ------------------ | ------------------------------------- |
| totalCount():&nbsp;number | - | Obtains the total number of data records. | | totalCount(): number | - | Obtains the total number of data records. |
| getData(index:&nbsp;number):&nbsp;any | number | Obtains the data record corresponding to the specified index.<br>**index**: index of the data record to obtain.| | getData(index: number): any | number | Obtains the data record corresponding to the specified index.<br>**index**: index of the data record to obtain.|
| registerDataChangeListener(listener:DataChangeListener):&nbsp;void | DataChangeListener | Registers a listener for data changes.<br>**listener**: listener for data changes. | | registerDataChangeListener(listener:DataChangeListener): void | DataChangeListener | Registers a listener for data changes.<br>**listener**: listener for data changes. |
| unregisterDataChangeListener(listener:DataChangeListener):&nbsp;void | DataChangeListener | Deregisters the listener for data changes.<br>**listener**: listener for data changes. | | unregisterDataChangeListener(listener:DataChangeListener): void | DataChangeListener | Deregisters the listener for data changes.<br>**listener**: listener for data changes. |
## Description of DataChangeListener ## Description of DataChangeListener
...@@ -77,20 +77,20 @@ interface DataChangeListener { ...@@ -77,20 +77,20 @@ interface DataChangeListener {
| Declaration | Parameter Type | Description | | Declaration | Parameter Type | Description |
| ------------------------------------------------------------ | -------------------------------------- | ------------------------------------------------------------ | | ------------------------------------------------------------ | -------------------------------------- | ------------------------------------------------------------ |
| onDataReloaded():&nbsp;void | - | Invoked when all data is reloaded. | | onDataReloaded(): void | - | Invoked when all data is reloaded. |
| onDataAdded(index:&nbsp;number):void<sup>(deprecated)</sup> | number | Invoked when data is added to the position indicated by the specified index.<br>This API is deprecated since API version 8. You are advised to use **onDataAdd** instead.<br>**index**: index of the position where data is added.| | onDataAdd(index: number): void<sup>8+</sup> | number | Invoked when data is added to the position indicated by the specified index.<br>**index**: index of the position where data is added.|
| onDataMoved(from:&nbsp;number,&nbsp;to:&nbsp;number):&nbsp;void<sup>(deprecated)</sup> | from:&nbsp;number,<br>to:&nbsp;number | Invoked when data is moved.<br>This API is deprecated since API version 8. You are advised to use **onDataMove** instead.<br>**from**: original position of data; **to**: target position of data.<br>**NOTE**<br>The ID must remain unchanged before and after data movement. If the ID changes, APIs for deleting and adding data must be called.| | onDataMove(from: number, to: number): void<sup>8+</sup> | from: number,<br>to: number | Invoked when data is moved.<br>**from**: original position of data; **to**: target position of data.<br>**NOTE**<br>The ID must remain unchanged before and after data movement. If the ID changes, APIs for deleting and adding data must be called.|
| onDataDeleted(index: number):void<sup>(deprecated)</sup> | number | Invoked when data is deleted from the position indicated by the specified index. LazyForEach will update the displayed content accordingly.<br>This API is deprecated since API version 8. You are advised to use **onDataDelete** instead.<br>**index**: index of the position where data is deleted.|
| onDataChanged(index:&nbsp;number):&nbsp;void<sup>(deprecated)</sup> | number | Invoked when data in the position indicated by the specified index is changed.<br>This API is deprecated since API version 8. You are advised to use **onDataChange** instead.<br>**index**: listener for data changes.|
| onDataAdd(index:&nbsp;number):&nbsp;void<sup>8+</sup> | number | Invoked when data is added to the position indicated by the specified index.<br>**index**: index of the position where data is added.|
| onDataMove(from:&nbsp;number,&nbsp;to:&nbsp;number):&nbsp;void<sup>8+</sup> | from:&nbsp;number,<br>to:&nbsp;number | Invoked when data is moved.<br>**from**: original position of data; **to**: target position of data.<br>**NOTE**<br>The ID must remain unchanged before and after data movement. If the ID changes, APIs for deleting and adding data must be called.|
| onDataDelete(index: number):void<sup>8+</sup> | number | Invoked when data is deleted from the position indicated by the specified index. LazyForEach will update the displayed content accordingly.<br>**index**: index of the position where data is deleted.<br>**NOTE**<br>Before **onDataDelete** is called, ensure that the corresponding data in **dataSource** has been deleted. Otherwise, undefined behavior will occur during page rendering.| | onDataDelete(index: number):void<sup>8+</sup> | number | Invoked when data is deleted from the position indicated by the specified index. LazyForEach will update the displayed content accordingly.<br>**index**: index of the position where data is deleted.<br>**NOTE**<br>Before **onDataDelete** is called, ensure that the corresponding data in **dataSource** has been deleted. Otherwise, undefined behavior will occur during page rendering.|
| onDataChange(index:&nbsp;number):&nbsp;void<sup>8+</sup> | number | Invoked when data in the position indicated by the specified index is changed.<br>**index**: index of the position where data is changed.| | onDataChange(index: number): void<sup>8+</sup> | number | Invoked when data in the position indicated by the specified index is changed.<br>**index**: index of the position where data is changed.|
| onDataAdded(index: number):void<sup>(deprecated)</sup> | number | Invoked when data is added to the position indicated by the specified index.<br>This API is deprecated since API version 8. You are advised to use **onDataAdd** instead.<br>**index**: index of the position where data is added.|
| onDataMoved(from: number, to: number): void<sup>(deprecated)</sup> | from: number,<br>to: number | Invoked when data is moved.<br>This API is deprecated since API version 8. You are advised to use **onDataMove** instead.<br>**from**: original position of data; **to**: target position of data.<br>**NOTE**<br>The ID must remain unchanged before and after data movement. If the ID changes, APIs for deleting and adding data must be called.|
| onDataDeleted(index: number):void<sup>(deprecated)</sup> | number | Invoked when data is deleted from the position indicated by the specified index. LazyForEach will update the displayed content accordingly.<br>This API is deprecated since API version 8. You are advised to use **onDataDelete** instead.<br>**index**: index of the position where data is deleted.|
| onDataChanged(index: number): void<sup>(deprecated)</sup> | number | Invoked when data in the position indicated by the specified index is changed.<br>This API is deprecated since API version 8. You are advised to use **onDataChange** instead.<br>**index**: listener for data changes.|
## Restrictions ## Restrictions
- **LazyForEach** must be used in the container component. Only the **\<List>**, **\<Grid>**, and **\<Swiper>** components support lazy loading (that is, only the visible part and a small amount of data before and after the visible part are loaded for caching). For other components, all data is loaded at the same time. - LazyForEach must be used in the container component. Only the [\<List>](../reference/arkui-ts/ts-container-list.md), [\<Grid>](../reference/arkui-ts/ts-container-grid.md), and [\<Swiper>](../reference/arkui-ts/ts-container-swiper.md) components support lazy loading (that is, only the visible part and a small amount of data before and after the visible part are loaded for caching). For other components, all data is loaded at the same time.
- **LazyForEach** must create one and only one child component in each iteration. - **LazyForEach** must create one and only one child component in each iteration.
...@@ -177,7 +177,7 @@ class BasicDataSource implements IDataSource { ...@@ -177,7 +177,7 @@ class BasicDataSource implements IDataSource {
} }
class MyDataSource extends BasicDataSource { class MyDataSource extends BasicDataSource {
private dataArray: string[] = ['/path/image0', '/path/image1', '/path/image2', '/path/image3']; private dataArray: string[] = [];
public totalCount(): number { public totalCount(): number {
return this.dataArray.length; return this.dataArray.length;
...@@ -201,6 +201,12 @@ class MyDataSource extends BasicDataSource { ...@@ -201,6 +201,12 @@ class MyDataSource extends BasicDataSource {
@Entry @Entry
@Component @Component
struct MyComponent { struct MyComponent {
aboutToAppear() {
for (var i = 100; i >= 80; i--) {
this.data.pushData(`Hello ${i}`)
}
}
private data: MyDataSource = new MyDataSource(); private data: MyDataSource = new MyDataSource();
build() { build() {
...@@ -208,15 +214,17 @@ struct MyComponent { ...@@ -208,15 +214,17 @@ struct MyComponent {
LazyForEach(this.data, (item: string) => { LazyForEach(this.data, (item: string) => {
ListItem() { ListItem() {
Row() { Row() {
Image(item).width('30%').height(50) Text(item).fontSize(50)
Text(item).fontSize(20).margin({ left: 10 }) .onAppear(() => {
console.info("appear:" + item)
})
}.margin({ left: 10, right: 10 }) }.margin({ left: 10, right: 10 })
} }
.onClick(() => { .onClick(() => {
this.data.pushData('/path/image' + this.data.totalCount()); this.data.pushData(`Hello ${this.data.totalCount()}`);
}) })
}, item => item) }, item => item)
} }.cachedCount(5)
} }
} }
``` ```
...@@ -25,21 +25,21 @@ An @State decorated variable, like all other decorated variables in the declarat ...@@ -25,21 +25,21 @@ An @State decorated variable, like all other decorated variables in the declarat
## Rules of Use ## Rules of Use
| \@State Decorator| Description | | \@State Decorator | Description |
| ------------ | ---------------------------------------- | | ------------------ | ------------------------------------------------------------ |
| Decorator parameters | None. | | Decorator parameters | None. |
| Synchronization type | Does not synchronize with any type of variable in the parent component. | | Synchronization type | Does not synchronize with any type of variable in the parent component. |
| Allowed variable types | Object, class, string, number, Boolean, enum, and array of these types. For details about the scenarios of nested types, see [Observed Changes](#observed-changes).<br>The type must be specified.<br>**any** is not supported. A combination of simple and complex types is not supported. The **undefined** and **null** values are not allowed.<br>**NOTE**<br>Avoid using this decorator to decorate the Date type, as doing so may lead to unexpected behavior of the application.<br>The Length, ResourceStr, and ResourceColor types are a combination of simple and complex types and therefore not supported.| | Allowed variable types| Object, class, string, number, Boolean, enum, and array of these types.<br>Date type.<br>For details about the scenarios of supported types, see [Observed Changes](#observed-changes).<br>The type must be specified.<br>**any** is not supported. A combination of simple and complex types is not supported. The **undefined** and **null** values are not allowed.<br>**NOTE**<br>The Length, ResourceStr, and ResourceColor types are a combination of simple and complex types and therefore not supported.|
| Initial value for the decorated variable | Mandatory. | | Initial value for the decorated variable| Local initialization is required. |
## Variable Transfer/Access Rules ## Variable Transfer/Access Rules
| Transfer/Access | Description | | Transfer/Access | Description |
| --------- | ---------------------------------------- | | ------------------ | ------------------------------------------------------------ |
| Initialization from the parent component | Optional. Initialization from the parent component or local initialization can be used.<br>An \@State decorated variable can be initialized from a regular variable or an \@State, \@Link, \@Prop, \@Provide, \@Consume, \@ObjectLink, \@StorageLink, \@StorageProp, \@LocalStorageLink, or \@LocalStorageProp decorated variable in its parent component.| | Initialization from the parent component | Optional. Initialization from the parent component or local initialization can be used. The initial value specified in the parent component will overwrite the one defined locally.<br>An \@State decorated variable can be initialized from a regular variable or an \@State, \@Link, \@Prop, \@Provide, \@Consume, \@ObjectLink, \@StorageLink, \@StorageProp, \@LocalStorageLink, or \@LocalStorageProp decorated variable in its parent component.|
| Subnode initialization | Supported. An \@State decorated variable can be used to initialize a regular variable or \@State, \@Link, \@Prop, or \@Provide decorated variable in the child component.| | Subnode initialization | Supported. An \@State decorated variable can be used to initialize a regular variable or \@State, \@Link, \@Prop, or \@Provide decorated variable in the child component.|
| Access| Private, accessible only within the component. | | Access| Private, accessible only within the component. |
**Figure 1** Initialization rule **Figure 1** Initialization rule
...@@ -153,6 +153,45 @@ Not all changes to state variables cause UI updates. Only changes that can be ob ...@@ -153,6 +153,45 @@ Not all changes to state variables cause UI updates. Only changes that can be ob
this.title.push(new Model(12)) this.title.push(new Model(12))
``` ```
- When the decorated variable is of the Date type, the overall value assignment of the Date object can be observed, and the following APIs can be called to update Date attributes: **setFullYear**, **setMonth**, **setDate**, **setHours**, **setMinutes**, **setSeconds**, **setMilliseconds**, **setTime**, **setUTCFullYear**, **setUTCMonth**, **setUTCDate**, **setUTCHours**, **setUTCMinutes**, **setUTCSeconds**, and **setUTCMilliseconds**.
```ts
@Entry
@Component
struct DatePickerExample {
@State selectedDate: Date = new Date('2021-08-08')
build() {
Column() {
Button('set selectedDate to 2023-07-08')
.margin(10)
.onClick(() => {
this.selectedDate = new Date('2023-07-08')
})
Button('increase the year by 1')
.margin(10)
.onClick(() => {
this.selectedDate.setFullYear(this.selectedDate.getFullYear() + 1)
})
Button('increase the month by 1')
.margin(10)
.onClick(() => {
this.selectedDate.setMonth(this.selectedDate.getMonth() + 1)
})
Button('increase the day by 1')
.margin(10)
.onClick(() => {
this.selectedDate.setDate(this.selectedDate.getDate() + 1)
})
DatePicker({
start: new Date('1970-1-1'),
end: new Date('2100-1-1'),
selected: this.selectedDate
})
}.width('100%')
}
}
```
### Framework Behavior ### Framework Behavior
...@@ -168,9 +207,9 @@ Not all changes to state variables cause UI updates. Only changes that can be ob ...@@ -168,9 +207,9 @@ Not all changes to state variables cause UI updates. Only changes that can be ob
### Decorating Variables of Simple Types ### Decorating Variables of Simple Types
In this example, \@State is used to decorate the **count** variable of the simple type and turns it into a state variable. The change of **count** causes the update of the **\<Button>** component. In this example, \@State is used to decorate the **count** variable of the simple type, turning it into a state variable. The change of **count** causes the update of the **\<Button>** component.
- When the state variable **count** changes, the framework searches for components that depend on this state variable, which include only the **\<Button>** component in this example. - When **count** changes, the framework searches for components bound to it, which include only the **\<Button>** component in this example.
- The framework executes the update method of the **\<Button>** component to implement on-demand update. - The framework executes the update method of the **\<Button>** component to implement on-demand update.
......
...@@ -2,7 +2,17 @@ ...@@ -2,7 +2,17 @@
A Harmony Archive (HAR) is a static shared package that can contain code, C++ libraries, resources, and configuration files. It enables modules and projects to share code related to ArkUI components, resources, and more. Unlike a Harmony Ability Package (HAP), a HAR cannot be independently installed on a device. Instead, it can be referenced only as the dependency of an application module. A Harmony Archive (HAR) is a static shared package that can contain code, C++ libraries, resources, and configuration files. It enables modules and projects to share code related to ArkUI components, resources, and more. Unlike a Harmony Ability Package (HAP), a HAR cannot be independently installed on a device. Instead, it can be referenced only as the dependency of an application module.
## Creating a HAR Module ## Creating a HAR Module
You can [create a HAR module in DevEco Studio](https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/creating_har_api9-0000001518082393-V3#section143510369612). To better protect your source code, enable obfuscation for the HAR module so that DevEco Studio compiles, obfuscates, and compresses code during HAR building. To enable obfuscation, open the **build-profile.json5** file of the HAR module and set **artifactType** to **obfuscation** as follows: You can [create a HAR module in DevEco Studio](https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/creating_har_api9-0000001518082393-V3#section143510369612).
To better protect your source code, enable obfuscation for the HAR module so that DevEco Studio compiles, obfuscates, and compresses code during HAR building.
> **NOTE**
>
> Obfuscation is only available for ArkTS projects in the stage model.
### Obfuscation in API Version 9
In API version 9, obfuscation is disabled by default, and can be enabled by setting **artifactType** to **obfuscation** in the **build-profile.json5** file of the HAR module. The configuration is as follows:
```json ```json
{ {
...@@ -16,9 +26,43 @@ The value options of **artifactType** are as follows, with the default value bei ...@@ -16,9 +26,43 @@ The value options of **artifactType** are as follows, with the default value bei
- **original**: Code is not obfuscated. - **original**: Code is not obfuscated.
- **obfuscation**: Code is obfuscated using Uglify. - **obfuscation**: Code is obfuscated using Uglify.
> **NOTE** ### Obfuscation in API Version 10
>
> Obfuscation is available only in the stage model. Therefore, if **artifactType** is set to **obfuscation**, **apiType** must be set to **stageMode**. In API version 10, obfuscation is enabled by default, and can be set through the **enable** field under **ruleOptions** in the **build-profile.json5** file of the HAR module. The configuration is as follows:
```json
{
"apiType": "stageMode",
"buildOption": {
},
"buildOptionSet": [
{
"name": "release",
"arkOptions": {
"obfuscation": {
"ruleOptions": {
"enable": true,
"files": [
"./obfuscation-rules.txt"
]
},
"consumerFiles": [
"./consumer-rules.txt"
]
}
}
},
],
"targets": [
{
"name": "default"
}
]
}
```
### Adaptation Guide
The **artifactType** field is forward compatible, and the original function is not affected. Yet, it is deprecated since API version 10, and you are advised to use the substitute as soon as possible.
## Precautions for HAR Development ## Precautions for HAR Development
- The HAR does not support the declaration of **abilities** and **extensionAbilities** in its configuration file. - The HAR does not support the declaration of **abilities** and **extensionAbilities** in its configuration file.
...@@ -95,7 +139,7 @@ To start with, [configure dependency](https://developer.harmonyos.com/cn/docs/do ...@@ -95,7 +139,7 @@ To start with, [configure dependency](https://developer.harmonyos.com/cn/docs/do
### Reference ArkUI Components in the HAR ### Reference ArkUI Components in the HAR
After configuring the dependency on the HAR, you can reference ArkUI components exported from the HAR by using **import**. The sample code is as follows: After configuring the dependency on the HAR, you can reference ArkUI components exported from the HAR by using **import**. The code snippet is as follows:
```js ```js
// entry/src/main/ets/pages/index.ets // entry/src/main/ets/pages/index.ets
import { MainPage } from "library" import { MainPage } from "library"
......
# Building the First ArkTS Application in Stage Model # Building the First ArkTS Application in Stage Model
> **NOTE** > **NOTE**
> >
> To use ArkTS, your DevEco Studio must be V3.0.0.900 Beta3 or later. > To use ArkTS, your DevEco Studio must be V3.0.0.900 Beta3 or later.
> >
> In this document, DevEco Studio 4.0 Beta1 is used. You can download it [here](../../release-notes/OpenHarmony-v4.0-beta1.md#version-mapping). > In this document, DevEco Studio 4.0 Beta2 is used. You can download it [here](../../release-notes/OpenHarmony-v4.0-beta2.md#version-mapping).
## Creating an ArkTS Project ## Creating an ArkTS Project
...@@ -21,16 +21,18 @@ The following describes how to create the OpenHarmony projects of API 10 and API ...@@ -21,16 +21,18 @@ The following describes how to create the OpenHarmony projects of API 10 and API
![createProject](figures/createProject.png) ![createProject](figures/createProject.png)
3. On the project configuration page, set **Compile SDK** to **3.1.0(API 9** and retain the default values for other parameters. 3. On the project configuration page, set **Compile SDK** to **3.1.0(API 9)** and retain the default values for other parameters.
The **Node** parameter sets the Node.js version to use for the project. You can use an existing version or download a new one.
![chooseStageModel](figures/chooseStageModel.png) ![chooseStageModel](figures/chooseStageModel.png)
> **NOTE** > **NOTE**
> >
> You can use the low-code development mode apart from the traditional coding approach. > You can use the low-code development mode apart from the traditional coding approach.
> >
> On the low-code development pages, you can design your application UI in an efficient, intuitive manner, with a wide array of UI editing features. > On the low-code development pages, you can design your application UI in an efficient, intuitive manner, with a wide array of UI editing features.
> >
> To use the low-code development mode, turn on **Enable Super Visual** on the page shown above. > To use the low-code development mode, turn on **Enable Super Visual** on the page shown above.
4. Click **Finish**. DevEco Studio will automatically generate the sample code and resources that match your project type. Wait until the project is created. 4. Click **Finish**. DevEco Studio will automatically generate the sample code and resources that match your project type. Wait until the project is created.
...@@ -43,12 +45,13 @@ The following describes how to create the OpenHarmony projects of API 10 and API ...@@ -43,12 +45,13 @@ The following describes how to create the OpenHarmony projects of API 10 and API
![targetSdkVersion](figures/targetSdkVersion.png) ![targetSdkVersion](figures/targetSdkVersion.png)
7. Delete the **runtimeOS** configuration from the **targets** field in all module-level **build-profile.json5** files. 7. Delete the **runtimeOS** configuration from the **targets** field in the module-level **build-profile.json5** files.
![deleteRuntimeOS](figures/deleteRuntimeOS.png) ![deleteRuntimeOS](figures/deleteRuntimeOS.png)
8. Click **Sync Now** and wait until the synchronization is complete. A project of API version 10 is now created. 8. Click **Sync Now** and wait until the synchronization is complete. A project of API version 10 is now created.
### Creating a Project of API Version 9 ### Creating a Project of API Version 9
1. If you are opening DevEco Studio for the first time, click **Create Project**. If a project is already open, choose **File** > **New** > **Create Project** from the menu bar. 1. If you are opening DevEco Studio for the first time, click **Create Project**. If a project is already open, choose **File** > **New** > **Create Project** from the menu bar.
...@@ -57,16 +60,18 @@ The following describes how to create the OpenHarmony projects of API 10 and API ...@@ -57,16 +60,18 @@ The following describes how to create the OpenHarmony projects of API 10 and API
![createProject](figures/createProject.png) ![createProject](figures/createProject.png)
3. On the project configuration page, set **Compile SDK** to **3.1.0(API 9** and retain the default values for other parameters. 3. On the project configuration page, set **Compile SDK** to **3.1.0(API 9)** and retain the default values for other parameters.
The **Node** parameter sets the Node.js version to use for the project. You can use an existing version or download a new one.
![chooseStageModel](figures/chooseStageModel.png) ![chooseStageModel](figures/chooseStageModel.png)
> **NOTE** > **NOTE**
> >
> You can use the low-code development mode apart from the traditional coding approach. > You can use the low-code development mode apart from the traditional coding approach.
> >
> On the low-code development pages, you can design your application UI in an efficient, intuitive manner, with a wide array of UI editing features. > On the low-code development pages, you can design your application UI in an efficient, intuitive manner, with a wide array of UI editing features.
> >
> To use the low-code development mode, turn on **Enable Super Visual** on the page shown above. > To use the low-code development mode, turn on **Enable Super Visual** on the page shown above.
4. Click **Finish**. DevEco Studio will automatically generate the sample code and resources that match your project type. Wait until the project is created. 4. Click **Finish**. DevEco Studio will automatically generate the sample code and resources that match your project type. Wait until the project is created.
...@@ -78,11 +83,11 @@ The following describes how to create the OpenHarmony projects of API 10 and API ...@@ -78,11 +83,11 @@ The following describes how to create the OpenHarmony projects of API 10 and API
## ArkTS Project Directory Structure (Stage Model, API Version 10) ## ArkTS Project Directory Structure (Stage Model, API Version 10)
![en-us_image_0000001364054489](figures/en-us_image_0000001364054489.png) ![project](figures/project.png)
- **AppScope > app.json5**: application-level configuration information. - **AppScope > app.json5**: application-level configuration information.
- **entry**: OpenHarmony project module, which can be built into an OpenHarmony Ability Package ([HAP](../../glossary.md#hap)). - **entry**: OpenHarmony project module, which can be built into an ability package (HAP).
- **src > main > ets**: a collection of ArkTS source code. - **src > main > ets**: a collection of ArkTS source code.
- **src > main > ets > entryability**: entry to your application/service. - **src > main > ets > entryability**: entry to your application/service.
...@@ -99,17 +104,18 @@ The following describes how to create the OpenHarmony projects of API 10 and API ...@@ -99,17 +104,18 @@ The following describes how to create the OpenHarmony projects of API 10 and API
- **oh_modules**: third-party library dependency information. For details about how to adapt a historical npm project to ohpm, see [Manually Migrating Historical Projects](https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/project_overview-0000001053822398-V3#section108143331212). - **oh_modules**: third-party library dependency information. For details about how to adapt a historical npm project to ohpm, see [Manually Migrating Historical Projects](https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/project_overview-0000001053822398-V3#section108143331212).
- **build-profile.json5**: application-level configuration options, including **signingConfigs** and **products**. The **runtimeOS** field in **products** indicates the runtime OS. Its default value is **HarmonyOS**. If you are developing an OpenHarmony application, change the value to **OpenHarmony**. - **build-profile.json5**: application-level configuration information, including the **signingConfigs** and **products** configuration. The **runtimeOS** field in **products** indicates the runtime OS. Its default value is **HarmonyOS**. If you are developing an OpenHarmony application, change the value to **OpenHarmony**.
- **hvigorfile.ts**: application-level build script. - **hvigorfile.ts**: application-level build script.
## ArkTS Project Directory Structure (Stage Model, API Version 9) ## ArkTS Project Directory Structure (Stage Model, API Version 9)
![en-us_image_0000001364054489](figures/en-us_image_0000001364054489.png) ![project](figures/project.png)
- **AppScope > app.json5**: application-level configuration information. - **AppScope > app.json5**: application-level configuration information.
- **entry**: OpenHarmony project module, which can be built into an OpenHarmony Ability Package ([HAP](../../glossary.md#hap)). - **entry**: OpenHarmony project module, which can be built into an ability package (HAP).
- **src > main > ets**: a collection of ArkTS source code. - **src > main > ets**: a collection of ArkTS source code.
- **src > main > ets > entryability**: entry to your application/service. - **src > main > ets > entryability**: entry to your application/service.
...@@ -267,7 +273,7 @@ You can implement page redirection through the [page router](../reference/apis/j ...@@ -267,7 +273,7 @@ You can implement page redirection through the [page router](../reference/apis/j
1. Implement redirection from the first page to the second page. 1. Implement redirection from the first page to the second page.
In the **index.ets** file of the first page, bind the **onClick** event to the **Next** button so that clicking the button redirects the user to the second page. The sample code in the **Index.ets** file is shown below: In the **Index.ets** file of the first page, bind the **onClick** event to the **Next** button so that clicking the button redirects the user to the second page. The sample code in the **Index.ets** file is shown below:
```ts ```ts
// Index.ets // Index.ets
......
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
- [@ohos.app.ability.ServiceExtensionAbility (ServiceExtensionAbility)](js-apis-app-ability-serviceExtensionAbility.md) - [@ohos.app.ability.ServiceExtensionAbility (ServiceExtensionAbility)](js-apis-app-ability-serviceExtensionAbility.md)
- [@ohos.app.ability.StartOptions (StartOptions)](js-apis-app-ability-startOptions.md) - [@ohos.app.ability.StartOptions (StartOptions)](js-apis-app-ability-startOptions.md)
- [@ohos.app.ability.UIAbility (UIAbility)](js-apis-app-ability-uiAbility.md) - [@ohos.app.ability.UIAbility (UIAbility)](js-apis-app-ability-uiAbility.md)
- [@ohos.app.ability.UIExtensionAbility (Base Class for ExtensionAbilities with UI)](js-apis-app-ability-uiExtensionAbility.md)
- [@ohos.app.ability.UIExtensionContentSession (UI Operation Class for ExtensionAbilities with UI)](js-apis-app-ability-uiExtensionContentSession.md)
- [@ohos.app.form.FormExtensionAbility (FormExtensionAbility)](js-apis-app-form-formExtensionAbility.md) - [@ohos.app.form.FormExtensionAbility (FormExtensionAbility)](js-apis-app-form-formExtensionAbility.md)
- [@ohos.application.DataShareExtensionAbility (DataShareExtensionAbility)](js-apis-application-dataShareExtensionAbility.md) - [@ohos.application.DataShareExtensionAbility (DataShareExtensionAbility)](js-apis-application-dataShareExtensionAbility.md)
- [@ohos.application.StaticSubscriberExtensionAbility (StaticSubscriberExtensionAbility)](js-apis-application-staticSubscriberExtensionAbility.md) - [@ohos.application.StaticSubscriberExtensionAbility (StaticSubscriberExtensionAbility)](js-apis-application-staticSubscriberExtensionAbility.md)
...@@ -42,6 +44,7 @@ ...@@ -42,6 +44,7 @@
- [@ohos.app.form.formBindingData (formBindingData)](js-apis-app-form-formBindingData.md) - [@ohos.app.form.formBindingData (formBindingData)](js-apis-app-form-formBindingData.md)
- [@ohos.app.form.formHost (FormHost)](js-apis-app-form-formHost.md) - [@ohos.app.form.formHost (FormHost)](js-apis-app-form-formHost.md)
- [@ohos.app.form.formInfo (FormInfo)](js-apis-app-form-formInfo.md) - [@ohos.app.form.formInfo (FormInfo)](js-apis-app-form-formInfo.md)
- [@ohos.app.form.formObserver (formObserver)](js-apis-app-form-formObserver.md)
- [@ohos.app.form.formProvider (FormProvider)](js-apis-app-form-formProvider.md) - [@ohos.app.form.formProvider (FormProvider)](js-apis-app-form-formProvider.md)
- [@ohos.application.uriPermissionManager (URI Permission Management)](js-apis-uripermissionmanager.md) - [@ohos.application.uriPermissionManager (URI Permission Management)](js-apis-uripermissionmanager.md)
- Both Models (To Be Deprecated Soon) - Both Models (To Be Deprecated Soon)
...@@ -106,6 +109,7 @@ ...@@ -106,6 +109,7 @@
- [ProcessInformation](js-apis-inner-application-processInformation.md) - [ProcessInformation](js-apis-inner-application-processInformation.md)
- [ServiceExtensionContext](js-apis-inner-application-serviceExtensionContext.md) - [ServiceExtensionContext](js-apis-inner-application-serviceExtensionContext.md)
- [UIAbilityContext](js-apis-inner-application-uiAbilityContext.md) - [UIAbilityContext](js-apis-inner-application-uiAbilityContext.md)
- [UIExtensionContext](js-apis-inner-application-uiExtensionContext.md)
- [shellCmdResult](js-apis-inner-application-shellCmdResult.md) - [shellCmdResult](js-apis-inner-application-shellCmdResult.md)
- [WindowExtensionContext](js-apis-inner-application-windowExtensionContext.md) - [WindowExtensionContext](js-apis-inner-application-windowExtensionContext.md)
- wantAgent - wantAgent
...@@ -198,6 +202,7 @@ ...@@ -198,6 +202,7 @@
- UI Page - UI Page
- [@ohos.animator (Animator)](js-apis-animator.md) - [@ohos.animator (Animator)](js-apis-animator.md)
- [@ohos.arkui.componentSnapshot (Component Snapshot)](js-apis-arkui-componentSnapshot.md) - [@ohos.arkui.componentSnapshot (Component Snapshot)](js-apis-arkui-componentSnapshot.md)
- [@ohos.arkui.componentUtils (componentUtils)](js-apis-arkui-componentUtils.md)
- [@ohos.arkui.dragController (DragController)](js-apis-arkui-dragController.md) - [@ohos.arkui.dragController (DragController)](js-apis-arkui-dragController.md)
- [@ohos.arkui.drawableDescriptor (DrawableDescriptor)](js-apis-arkui-drawableDescriptor.md) - [@ohos.arkui.drawableDescriptor (DrawableDescriptor)](js-apis-arkui-drawableDescriptor.md)
- [@ohos.arkui.inspector (Layout Callback)](js-apis-arkui-inspector.md) - [@ohos.arkui.inspector (Layout Callback)](js-apis-arkui-inspector.md)
...@@ -205,12 +210,13 @@ ...@@ -205,12 +210,13 @@
- [@ohos.curves (Interpolation Calculation)](js-apis-curve.md) - [@ohos.curves (Interpolation Calculation)](js-apis-curve.md)
- [@ohos.font (Custom Font Registration)](js-apis-font.md) - [@ohos.font (Custom Font Registration)](js-apis-font.md)
- [@ohos.matrix4 (Matrix Transformation)](js-apis-matrix4.md) - [@ohos.matrix4 (Matrix Transformation)](js-apis-matrix4.md)
- [@ohos.measure (Text Measurement)](js-apis-measure.md)
- [@ohos.mediaquery (Media Query)](js-apis-mediaquery.md) - [@ohos.mediaquery (Media Query)](js-apis-mediaquery.md)
- [@ohos.pluginComponent (PluginComponentManager)](js-apis-plugincomponent.md) - [@ohos.pluginComponent (PluginComponentManager)](js-apis-plugincomponent.md)
- [@ohos.promptAction (Prompt)](js-apis-promptAction.md) - [@ohos.promptAction (Prompt)](js-apis-promptAction.md)
- [@ohos.router (Page Routing)](js-apis-router.md) - [@ohos.router (Page Routing)](js-apis-router.md)
- [@ohos.measure (Text Measurement)](js-apis-measure.md)
- [@ohos.uiAppearance (UI Appearance)](js-apis-uiappearance.md) - [@ohos.uiAppearance (UI Appearance)](js-apis-uiappearance.md)
- Graphics - Graphics
- [@ohos.animation.windowAnimationManager (Window Animation Management)](js-apis-windowAnimationManager.md) - [@ohos.animation.windowAnimationManager (Window Animation Management)](js-apis-windowAnimationManager.md)
- [@ohos.application.WindowExtensionAbility (WindowExtensionAbility)](js-apis-application-windowExtensionAbility.md) - [@ohos.application.WindowExtensionAbility (WindowExtensionAbility)](js-apis-application-windowExtensionAbility.md)
...@@ -225,12 +231,15 @@ ...@@ -225,12 +231,15 @@
- [WebGL2](js-apis-webgl2.md) - [WebGL2](js-apis-webgl2.md)
- Multimedia - Multimedia
- [@ohos.app.ability.MediaControlExtensionAbility (ExtensionAbility for Media Playback Control)](js-apis-app-ability-MediaControlExtensionAbility.md)
- [@ohos.multimedia.audio (Audio Management)](js-apis-audio.md) - [@ohos.multimedia.audio (Audio Management)](js-apis-audio.md)
- [@ohos.multimedia.avsession (AVSession Management)](js-apis-avsession.md) - [@ohos.multimedia.avsession (AVSession Management)](js-apis-avsession.md)
- [@ohos.multimedia.camera (Camera Management)](js-apis-camera.md) - [@ohos.multimedia.camera (Camera Management)](js-apis-camera.md)
- [@ohos.multimedia.image (Image Processing)](js-apis-image.md) - [@ohos.multimedia.image (Image Processing)](js-apis-image.md)
- [@ohos.multimedia.media (Media)](js-apis-media.md) - [@ohos.multimedia.media (Media)](js-apis-media.md)
- [@ohos.multimedia.systemSoundManager (System Sound Management)](js-apis-systemSoundManager.md) - [@ohos.multimedia.systemSoundManager (System Sound Management)](js-apis-systemSoundManager.md)
- application
- [MediaControlExtensionContext (ExtensionAbility Context for Media Playback Control)](js-apis-inner-application-MediaControlExtensionContext.md)
- multimedia - multimedia
- [ringtonePlayer (Ringtone Player)](js-apis-inner-multimedia-ringtonePlayer.md) - [ringtonePlayer (Ringtone Player)](js-apis-inner-multimedia-ringtonePlayer.md)
...@@ -313,20 +322,21 @@ ...@@ -313,20 +322,21 @@
- [@ohos.net.sharing (Network Sharing)](js-apis-net-sharing.md) - [@ohos.net.sharing (Network Sharing)](js-apis-net-sharing.md)
- [@ohos.net.socket (Socket Connection)](js-apis-socket.md) - [@ohos.net.socket (Socket Connection)](js-apis-socket.md)
- [@ohos.net.statistics (Traffic Management)](js-apis-net-statistics.md) - [@ohos.net.statistics (Traffic Management)](js-apis-net-statistics.md)
- [@ohos.net.vpn (VPN Management)](js-apis-net-vpn.md)
- [@ohos.net.webSocket (WebSocket Connection)](js-apis-webSocket.md) - [@ohos.net.webSocket (WebSocket Connection)](js-apis-webSocket.md)
- [@ohos.request (Upload and Download)](js-apis-request.md) - [@ohos.request (Upload and Download)](js-apis-request.md)
- Connectivity - Connectivity
- [@ohos.bluetooth.a2dp (Bluetooth a2dp Module)(Recommended)](js-apis-bluetooth-a2dp.md) - [@ohos.bluetooth.a2dp (Bluetooth A2DP Module) (Recommended)](js-apis-bluetooth-a2dp.md)
- [@ohos.bluetooth.access (Bluetooth access Module)(Recommended)](js-apis-bluetooth-access.md) - [@ohos.bluetooth.access (Bluetooth Access Module) (Recommended)](js-apis-bluetooth-access.md)
- [@ohos.bluetooth.baseProfile (Bluetooth baseProfile Module)(Recommended)](js-apis-bluetooth-baseProfile.md) - [@ohos.bluetooth.baseProfile (Bluetooth baseProfile Module) (Recommended)](js-apis-bluetooth-baseProfile.md)
- [@ohos.bluetooth.ble (Bluetooth ble Module)(Recommended)](js-apis-bluetooth-ble.md) - [@ohos.bluetooth.ble (Bluetooth BLE Module) (Recommended)](js-apis-bluetooth-ble.md)
- [@ohos.bluetooth.connection (Bluetooth connection Module)(Recommended)](js-apis-bluetooth-connection.md) - [@ohos.bluetooth.connection (Bluetooth connection Module) (Recommended)](js-apis-bluetooth-connection.md)
- [@ohos.bluetooth.constant (Bluetooth constant Module)(Recommended)](js-apis-bluetooth-constant.md) - [@ohos.bluetooth.constant (Bluetooth constant Module) (Recommended)](js-apis-bluetooth-constant.md)
- [@ohos.bluetooth.hfp (Bluetooth hfp Module)(Recommended)](js-apis-bluetooth-hfp.md) - [@ohos.bluetooth.hfp (Bluetooth hfp Module) (Recommended)](js-apis-bluetooth-hfp.md)
- [@ohos.bluetooth.hid (Bluetooth hid Module)(Recommended)(js-apis-bluetooth-hid.md) - [@ohos.bluetooth.hid (Bluetooth hid Module) (Recommended)](js-apis-bluetooth-hid.md)
- [@ohos.bluetooth.pan (Bluetooth pan Module)(Recommended)](js-apis-bluetooth-pan.md) - [@ohos.bluetooth.pan (Bluetooth pan Module) (Recommended)](js-apis-bluetooth-pan.md)
- [@ohos.bluetooth.socket (Bluetooth socket Module)(Recommended)](js-apis-bluetooth-socket.md) - [@ohos.bluetooth.socket (Bluetooth socket Module) (Recommended)](js-apis-bluetooth-socket.md)
- [@ohos.bluetooth (Bluetooth) (To Be Deprecated Soon)](js-apis-bluetooth.md) - [@ohos.bluetooth (Bluetooth) (To Be Deprecated Soon)](js-apis-bluetooth.md)
- [@ohos.bluetoothManager (Bluetooth) (To Be Deprecated Soon)](js-apis-bluetoothManager.md) - [@ohos.bluetoothManager (Bluetooth) (To Be Deprecated Soon)](js-apis-bluetoothManager.md)
- [@ohos.connectedTag (Active Tags)](js-apis-connectedTag.md) - [@ohos.connectedTag (Active Tags)](js-apis-connectedTag.md)
...@@ -385,6 +395,7 @@ ...@@ -385,6 +395,7 @@
- [@ohos.charger (Charging Type)](js-apis-charger.md) - [@ohos.charger (Charging Type)](js-apis-charger.md)
- [@ohos.cooperate (Screen Hopping)](js-apis-devicestatus-cooperate.md) - [@ohos.cooperate (Screen Hopping)](js-apis-devicestatus-cooperate.md)
- [@ohos.deviceAttest (Device Attestation)](js-apis-deviceAttest.md) - [@ohos.deviceAttest (Device Attestation)](js-apis-deviceAttest.md)
- [@ohos.deviceStatus.dragInteraction (Drag)](js-apis-devicestatus-draginteraction.md)
- [@ohos.deviceInfo (Device Information)](js-apis-device-info.md) - [@ohos.deviceInfo (Device Information)](js-apis-device-info.md)
- [@ohos.distributedDeviceManager (Device Management)](js-apis-distributedDeviceManager.md) - [@ohos.distributedDeviceManager (Device Management)](js-apis-distributedDeviceManager.md)
- [@ohos.distributedHardware.deviceManager (Device Management)](js-apis-device-manager.md) - [@ohos.distributedHardware.deviceManager (Device Management)](js-apis-device-manager.md)
...@@ -405,6 +416,7 @@ ...@@ -405,6 +416,7 @@
- [@ohos.multimodalInput.touchEvent (Touch Event)](js-apis-touchevent.md) - [@ohos.multimodalInput.touchEvent (Touch Event)](js-apis-touchevent.md)
- [@ohos.multimodalInput.shortKey (Shortcut Key)](js-apis-shortKey.md) - [@ohos.multimodalInput.shortKey (Shortcut Key)](js-apis-shortKey.md)
- [@ohos.power (System Power Management)](js-apis-power.md) - [@ohos.power (System Power Management)](js-apis-power.md)
- [@ohos.resourceschedule.deviceStandby (Device Standby)](js-apis-resourceschedule-deviceStandby.md)
- [@ohos.runningLock (Runninglock)](js-apis-runninglock.md) - [@ohos.runningLock (Runninglock)](js-apis-runninglock.md)
- [@ohos.sensor (Sensor)](js-apis-sensor.md) - [@ohos.sensor (Sensor)](js-apis-sensor.md)
- [@ohos.settings (Data Item Settings)](js-apis-settings.md) - [@ohos.settings (Data Item Settings)](js-apis-settings.md)
...@@ -420,10 +432,9 @@ ...@@ -420,10 +432,9 @@
- Account Management - Account Management
- [@ohos.account.appAccount (App Account Management)](js-apis-appAccount.md) - [@ohos.account.appAccount (App Account Management)](js-apis-appAccount.md)
- [@ohos.account.appAccount.AuthorizationExtensionAbility (App AuthorizationExtensionAbility)](js-apis-appAccount-authorizationExtensionAbility.md)
- [@ohos.account.distributedAccount (Distributed Account Management)](js-apis-distributed-account.md) - [@ohos.account.distributedAccount (Distributed Account Management)](js-apis-distributed-account.md)
- [@ohos.account.osAccount (OS Account Management)](js-apis-osAccount.md) - [@ohos.account.osAccount (OS Account Management)](js-apis-osAccount.md)
- Customization - Customization
- [@ohos.configPolicy (Configuration Policy)](js-apis-configPolicy.md) - [@ohos.configPolicy (Configuration Policy)](js-apis-configPolicy.md)
......
# @ohos.WorkSchedulerExtensionAbility (Deferred Task Scheduling Callbacks) # @ohos.WorkSchedulerExtensionAbility (Deferred Task Scheduling Callbacks)
The **WorkSchedulerExtensionAbility** module provides callbacks for deferred task scheduling. The **WorkSchedulerExtensionAbility** module provides callbacks for deferred task scheduling. You can override the APIs provided by this module. When a deferred task is triggered, the system calls back the application through the APIs and processes the task logic in the callback.
When developing an application, you can override the APIs of this module and add your own task logic to the APIs.
> **NOTE** > **NOTE**
> >
> - The initial APIs of this module are supported since API version 9. Newly added APIs will be marked with a superscript to indicate their earliest API version. > - The initial APIs of this module are supported since API version 9. Newly added APIs will be marked with a superscript to indicate their earliest API version.
>
> - The APIs of this module can be used only in the stage model. > - The APIs of this module can be used only in the stage model.
## Modules to Import ## Modules to Import
```ts ```ts
...@@ -36,7 +34,7 @@ Called when the system starts scheduling the deferred task. ...@@ -36,7 +34,7 @@ Called when the system starts scheduling the deferred task.
| Name | Type | Mandatory | Description | | Name | Type | Mandatory | Description |
| ---- | ---------------------------------------- | ---- | -------------- | | ---- | ---------------------------------------- | ---- | -------------- |
| work | [workScheduler.WorkInfo](js-apis-resourceschedule-workScheduler.md#workinfo) | Yes | Target task.| | work | [workScheduler.WorkInfo](js-apis-resourceschedule-workScheduler.md#workinfo) | Yes | Deferred task that starts.|
**Example** **Example**
...@@ -60,7 +58,7 @@ Called when the system stops scheduling the deferred task. ...@@ -60,7 +58,7 @@ Called when the system stops scheduling the deferred task.
| Name | Type | Mandatory | Description | | Name | Type | Mandatory | Description |
| ---- | ---------------------------------------- | ---- | -------------- | | ---- | ---------------------------------------- | ---- | -------------- |
| work | [workScheduler.WorkInfo](js-apis-resourceschedule-workScheduler.md#workinfo) | Yes | Target task.| | work | [workScheduler.WorkInfo](js-apis-resourceschedule-workScheduler.md#workinfo) | Yes | Deferred task that stops.|
**Example** **Example**
......
...@@ -257,7 +257,7 @@ Defines animator options. ...@@ -257,7 +257,7 @@ Defines animator options.
| Name | Type | Mandatory| Description | | Name | Type | Mandatory| Description |
| ---------- | ----------------------------------------------------------- | ---- | ------------------------------------------------------------ | | ---------- | ----------------------------------------------------------- | ---- | ------------------------------------------------------------ |
| duration | number | Yes | Duration for playing the animation, in milliseconds. | | duration | number | Yes | Duration for playing the animation, in milliseconds. |
| easing | string | Yes | Animation interpolation curve. Only the following values are supported:<br>**"linear"**: The animation speed keeps unchanged.<br>**"ease"**: The animation starts slowly, accelerates, and then slows down towards the end. The cubic-bezier curve (0.25, 0.1, 0.25, 1.0) is used.<br>**"ease-in"**: The animation starts at a low speed and then picks up speed until the end. The cubic-bezier curve (0.42, 0.0, 1.0, 1.0) is used.<br>**"ease-out"**: The animation ends at a low speed. The cubic-bezier curve (0.0, 0.0, 0.58, 1.0) is used.<br>**"ease-in-out"**: The animation starts and ends at a low speed. The cubic-bezier curve (0.42, 0.0, 0.58, 1.0) is used.<br>**"fast-out-slow-in"**: The animation uses the standard cubic-bezier curve (0.4, 0.0, 0.2, 1.0).<br>**"linear-out-slow-in"**: The animation uses the deceleration cubic-bezier curve (0.0, 0.0, 0.2, 1.0).<br>**"friction"**: The animation uses the damping cubic-bezier curve (0.2, 0.0, 0.2, 1.0).<br>**"extreme-deceleration"**: The animation uses the extreme deceleration cubic-bezier curve (0.0, 0.0, 0.0, 1.0).<br>**"rhythm"**: The animation uses the rhythm cubic-bezier curve (0.7, 0.0, 0.2, 1.0).<br>**"sharp"**: The animation uses the sharp cubic-bezier curve (0.33, 0.0, 0.67, 1.0).<br>**"smooth"**: The animation uses the smooth cubic-bezier curve (0.4, 0.0, 0.4, 1.0).<br>**cubic-bezier(x1, y1, x2, y2)**: The animation uses the defined cubic-bezier curve, where the value of the input parameters must range from 0 to 1.<br>**steps(number, step-position)**: The animation uses a step curve. The **number** must be set and only an integer is supported. **step-position** is optional. It can be set to **start** or **end**. The default value is **end**.| | easing | string | Yes | Animation interpolation curve. Only the following values are supported:<br>**"linear"**: The animation speed keeps unchanged.<br>**"ease"**: The animation starts slowly, accelerates, and then slows down towards the end. The cubic-bezier curve (0.25, 0.1, 0.25, 1.0) is used.<br>**"ease-in"**: The animation starts at a low speed and then picks up speed until the end. The cubic-bezier curve (0.42, 0.0, 1.0, 1.0) is used.<br>**"ease-out"**: The animation ends at a low speed. The cubic-bezier curve (0.0, 0.0, 0.58, 1.0) is used.<br>**"ease-in-out"**: The animation starts and ends at a low speed. The cubic-bezier curve (0.42, 0.0, 0.58, 1.0) is used.<br>**"fast-out-slow-in"**: The animation uses the standard cubic-bezier curve (0.4, 0.0, 0.2, 1.0).<br>**"linear-out-slow-in"**: The animation uses the deceleration cubic-bezier curve (0.0, 0.0, 0.2, 1.0).<br>**"friction"**: The animation uses the damping cubic-bezier curve (0.2, 0.0, 0.2, 1.0).<br>**"extreme-deceleration"**: The animation uses the extreme deceleration cubic-bezier curve (0.0, 0.0, 0.0, 1.0).<br>**"rhythm"**: The animation uses the rhythm cubic-bezier curve (0.7, 0.0, 0.2, 1.0).<br>**"sharp"**: The animation uses the sharp cubic-bezier curve (0.33, 0.0, 0.67, 1.0).<br>**"smooth"**: The animation uses the smooth cubic-bezier curve (0.4, 0.0, 0.4, 1.0).<br>**"cubic-bezier(x1,y1,x2,y2)"**: The animation uses the defined cubic bezier curve, where the value of **x1** and **x2** must range from 0 to 1. For example, **"cubic-bezier(0.42,0.0,0.58,1.0)"**.<br>**"steps(number,step-position)"**: The animation uses a step curve. The **number** parameter is mandatory and must be set to a positive integer. The **step-position** parameter is optional and can be set to **start** or **end** (default value). For example, **"steps(3,start)"**.|
| delay | number | Yes | Animation delay duration, in milliseconds. Value **0** means that there is no delay. | | delay | number | Yes | Animation delay duration, in milliseconds. Value **0** means that there is no delay. |
| fill | "none" \| "forwards" \| "backwards" \| "both" | Yes | State of the animated target after the animation is executed.<br>**"none"**: No style is applied to the target before or after the animation is executed.<br>**"forwards"**: The target keeps the state at the end of the animation (defined in the last key frame) after the animation is executed.<br>**"backwards"**: The animation uses the value defined in the first key frame during the **animation-delay**. When **animation-direction** is set to **normal** or **alternate**, the value in the **from** key frame is used. When **animation-direction** is set to **reverse** or **alternate-reverse**, the value in the **to** key frame is used.<br>**"both"**: The animation follows the **forwards** and **backwards** rules.| | fill | "none" \| "forwards" \| "backwards" \| "both" | Yes | State of the animated target after the animation is executed.<br>**"none"**: No style is applied to the target before or after the animation is executed.<br>**"forwards"**: The target keeps the state at the end of the animation (defined in the last key frame) after the animation is executed.<br>**"backwards"**: The animation uses the value defined in the first key frame during the **animation-delay**. When **animation-direction** is set to **normal** or **alternate**, the value in the **from** key frame is used. When **animation-direction** is set to **reverse** or **alternate-reverse**, the value in the **to** key frame is used.<br>**"both"**: The animation follows the **forwards** and **backwards** rules.|
| direction | "normal" \| "reverse" \| "alternate" \| "alternate-reverse" | Yes | Animation playback mode.<br>**"normal"**: plays the animation in forward loop mode.<br>**"reverse"**: plays the animation in reverse loop mode.<br>**"alternate"**: plays the animation in alternating loop mode. When the animation is played for an odd number of times, the playback is in forward direction. When the animation is played for an even number of times, the playback is in reverse direction.<br>**"alternate-reverse"**: plays the animation in reverse alternating loop mode. When the animation is played for an odd number of times, the playback is in reverse direction. When the animation is played for an even number of times, the playback is in forward direction.| | direction | "normal" \| "reverse" \| "alternate" \| "alternate-reverse" | Yes | Animation playback mode.<br>**"normal"**: plays the animation in forward loop mode.<br>**"reverse"**: plays the animation in reverse loop mode.<br>**"alternate"**: plays the animation in alternating loop mode. When the animation is played for an odd number of times, the playback is in forward direction. When the animation is played for an even number of times, the playback is in reverse direction.<br>**"alternate-reverse"**: plays the animation in reverse alternating loop mode. When the animation is played for an odd number of times, the playback is in reverse direction. When the animation is played for an even number of times, the playback is in forward direction.|
......
# @ohos.app.ability.MediaControlExtensionAbility (ExtensionAbility for Media Playback Control)
The **MediaControlExtensionAbility** module, inherited from [UIExtensionAbility](js-apis-app-ability-uiExtensionAbility.md), provides ExtensionAbilities for media playback control. No APIs are added. During actual development, you need to implement the APIs in the parent class to use the lifecycle and capabilities of UIExtensionAbilities. You cannot directly call the base class.
**System capability**: SystemCapability.Multimedia.AVSession.Core
> **NOTE**
>
> - The initial APIs of this module are supported since API version 10. Newly added APIs will be marked with a superscript to indicate their earliest API version.
> - The APIs of this module can be used only in the stage model.
> - The APIs provided by this module are system APIs.
## Modules to Import
```js
import MediaControlExtensionAbility from @ohos.app.ability.MediaControlExtensionAbility;
```
# @ohos.account.appAccount.AuthorizationExtensionAbility (App AuthorizationExtensionAbility)
The **AuthorizationExtensionAbility** module provides APIs for implementing authorization to app accounts based on the ExtensionAbility framework.
> **NOTE**
>
> The initial APIs of this module are supported since API version 10. Newly added APIs will be marked with a superscript to indicate their earliest API version.
## Modules to Import
```ts
import AuthorizationExtensionAbility, { AuthorizationRequest, AuthorizationCallback } from '@ohos.account.appAccount.AuthorizationExtensionAbility';
```
## AuthorizationRequest
Defines the app account authorization request.
**System API**: This is a system API.
**System capability**: SystemCapability.Account.AppAccount
| Name | Type | Readable| Writable| Description |
| --------- | ------------------------------- | ---- | ---- | ------------------------------------ |
| callerUid | number | Yes | No | UID of the caller.|
| parameters | [appAccount.AccountCapabilityRequest](js-apis-appAccount.md#accountcapabilityrequest10) | Yes | No | Service parameters.|
## AuthorizationCallback
Provides callbacks to be invoked during the app account authorization.
**System API**: This is a system API.
**System capability**: SystemCapability.Account.AppAccount
| Name | Type | Readable| Writable| Description |
| --------- | ------------------------------- | ---- | ---- | ------------------------------------ |
| onResult | AsyncCallback<[appAccount.AccountCapabilityResponse](js-apis-appAccount.md#accountcapabilityresponse10), { [key: string]: object }> | Yes | No | Callback invoked to return the authorization result.|
## AuthorizationExtensionAbility.onStartAuthorization
onStartAuthorization(request: AuthorizationRequest, callback: AuthorizationCallback): void
Called when an authorization request is received.
**System API**: This is a system API.
**System capability**: SystemCapability.Account.AppAccount
**Parameters**
| Name | Type | Mandatory | Description |
| -------- | ---------------------------------------- | ---- | ----------------------- |
| request | [AuthorizationRequest](#authorizationrequest) | Yes | Authorization request information.|
| callback | [AuthorizationCallback](#authorizationcallback) | Yes | Authorization callback object.|
**Example**
```ts
class MyAuthorizationExtensionAbility extends AuthorizationExtensionAbility {
onStartAuthorization(request: AuthorizationRequest, callback: AuthorizationCallback) {
console.log('onStartAuthorization, callerUid: ' + request.callerUid + ', parameters: ' + request.parameters);
let response = {
name: 'xxxx',
scopes: ['xxx', 'xxx']
};
callback.onResult(null, response);
}
};
```
...@@ -608,9 +608,9 @@ Obtains the size, position, translation, scaling, rotation, and affine matrix in ...@@ -608,9 +608,9 @@ Obtains the size, position, translation, scaling, rotation, and affine matrix in
**Return value** **Return value**
| Type | Description | | Type | Description |
| ------------- | ------------------------------------------------------------ | | -------------------------------------------------------- | ------------------------------------------------ |
| ComponentInfo | Size, position, translation, scaling, rotation, and affine matrix information of the component. | | [ComponentInfo](js-apis-arkui-componentUtils.md#componentinfo) | Size, position, translation, scaling, rotation, and affine matrix information of the component.|
**Example** **Example**
......
# @ohos.componentUtils (componentUtils) # @ohos.arkui.componentUtils (componentUtils)
The **componentUtils** module provides API for obtaining the coordinates and size of the drawing area of a component. The **componentUtils** module provides API for obtaining the coordinates and size of the drawing area of a component.
...@@ -13,7 +13,7 @@ The **componentUtils** module provides API for obtaining the coordinates and siz ...@@ -13,7 +13,7 @@ The **componentUtils** module provides API for obtaining the coordinates and siz
## Modules to Import ## Modules to Import
```js ```js
import componentUtils from '@ohos.componentUtils' import componentUtils from '@ohos.arkui.componentUtils'
``` ```
## componentUtils.getRectangleById ## componentUtils.getRectangleById
...@@ -43,86 +43,106 @@ let modePosition = componentUtils.getRectangleById("onClick"); ...@@ -43,86 +43,106 @@ let modePosition = componentUtils.getRectangleById("onClick");
## ComponentInfo ## ComponentInfo
| Name | Type | Description | **System capability**: SystemCapability.ArkUI.ArkUI.Full
| ---------------|------------ | -----------------------------|
| size | [Size](#size) | Component size. | | Name | Type | Mandatory | Description |
| localOffset | [Offset](#offset) | Offset of the component relative to the parent component. | | ---------------|------------ | -----------------------------| -----------------------------|
| windowOffset | [Offset](#offset) | Offset of the component relative to the window. | | size | [Size](#size) | Yes| Component size. |
| screenOffset | [Offset](#offset) | Offset of the component relative to the screen. | | localOffset | [Offset](#offset) | Yes| Offset of the component relative to the parent component. |
| translate | [TranslateResult](#translateresult) | Translation of the component. | | windowOffset | [Offset](#offset) | Yes| Offset of the component relative to the window. |
| scale | [ScaleResult](#scaleresult) | Scaling of the component. | | screenOffset | [Offset](#offset) | Yes| Offset of the component relative to the screen. |
| rotate | [RotateResult](#rotateresult) | Rotation of the component. | | translate | [TranslateResult](#translateresult) | Yes| Translation of the component. |
| transform | [Matrix4Result](#matrix4result) | Affine matrix of the component, which is a 4x4 matrix object created based on the input parameter. | | scale | [ScaleResult](#scaleresult) | Yes| Scaling of the component. |
| rotate | [RotateResult](#rotateresult) | Yes| Rotation of the component. |
| transform | [Matrix4Result](#matrix4result) | Yes| Affine matrix of the component, which is a 4x4 matrix object created based on the input parameter. |
### Size ### Size
| Name | Type| Description | **System capability**: SystemCapability.ArkUI.ArkUI.Full
| -------- | ---- | ----------------------------------|
| width | number | Component width. | | Name | Type| Mandatory| Description |
| height | number | Component height. | | -------- | ---- | ----------------------------------| ----------------------------------|
| width | number | Yes| Component width. |
| height | number | Yes| Component height. |
### Offset ### Offset
| Name | Type| Description | **System capability**: SystemCapability.ArkUI.ArkUI.Full
| --------| ---- | -----------------------------------|
| x | number | X coordinate. | | Name | Type| Mandatory| Description |
| y | number | Y coordinate. | | --------| ---- | -----------------------------------| -----------------------------------|
| x | number | Yes| X coordinate. |
| y | number | Yes| Y coordinate. |
### TranslateResult ### TranslateResult
| Name | Type| Description | **System capability**: SystemCapability.ArkUI.ArkUI.Full
| --------| ---- | -----------------------------------|
| x | number | Translation distance along the x-axis. | | Name | Type| Mandatory| Description |
| y | number | Translation distance along the y-axis. | | --------| ---- | -----------------------------------| -----------------------------------|
| z | number | Translation distance along the z-axis. | | x | number | Yes| Translation distance along the x-axis. |
| y | number | Yes| Translation distance along the y-axis. |
| z | number | Yes| Translation distance along the z-axis. |
### ScaleResult ### ScaleResult
| Name | Type| Description | **System capability**: SystemCapability.ArkUI.ArkUI.Full
| --------| ---- | -----------------------------------|
| x | number | Scale factor along the x-axis. | | Name | Type| Mandatory| Description |
| y | number | Scale factor along the y-axis. | | --------| ---- | -----------------------------------| -----------------------------------|
| z | number | Scale factor along the z-axis. | | x | number | Yes| Scale factor along the x-axis. |
| centerX | number | X coordinate of the center point. | | y | number | Yes| Scale factor along the y-axis. |
| centerY | number | Y coordinate of the center point. | | z | number | Yes| Scale factor along the z-axis. |
| centerX | number | Yes| X coordinate of the center point. |
| centerY | number | Yes| Y coordinate of the center point. |
### RotateResult ### RotateResult
| Name | Type| Description | **System capability**: SystemCapability.ArkUI.ArkUI.Full
| --------| ---- | -----------------------------------|
| x | number | X coordinate of the rotation vector. | | Name | Type| Mandatory| Description |
| y | number | Y coordinate of the rotation vector. | | --------| ---- | -----------------------------------| -----------------------------------|
| z | number | Z coordinate of the rotation vector. | | x | number | Yes| X coordinate of the rotation vector. |
| angle | number | Rotation angle. | | y | number | Yes| Y coordinate of the rotation vector. |
| centerX | number | X coordinate of the center point. | | z | number | Yes| Z coordinate of the rotation vector. |
| centerY | number | Y coordinate of the center point. | | angle | number | Yes| Rotation angle. |
| centerX | number | Yes| X coordinate of the center point. |
| centerY | number | Yes| Y coordinate of the center point. |
### Matrix4Result ### Matrix4Result
| Name | Type| Description | **System capability**: SystemCapability.ArkUI.ArkUI.Full
| --------| ---- | -----------------------------------|
| number | number | Scale factor along the x-axis. Defaults to **1** for the identity matrix. | | Value Range | Description |
| number | number | The second value, which is affected by the rotation of the x, y, and z axes.| | --------| -----------------------------------|
| number | number | The third value, which is affected by the rotation of the x, y, and z axes.| | [number,number,number,number,<br>number,number,number,number,<br>number,number,number,number,<br>number,number,number,number] | A number array whose length is 16 (4 x 4). For details, see **4 x 4 matrix description**.|
| number | number | Meaningless value. |
| number | number | The fifth value, which is affected by the rotation of the x, y, and z axes.| **4 x 4 matrix description**
| number | number | Scale factor along the y-axis. Defaults to **1** for the identity matrix. |
| number | number | The seventh value, which is affected by the rotation of the x, y, and z axes.| | Name| Type | Mandatory| Description |
| number | number | Meaningless value. | | ------ | ------ | ---- | ------------------------------------ |
| number | number | The ninth value, which is affected by the rotation of the x, y, and z axes.| | m00 | number | Yes | Scale factor along the x-axis. Defaults to **1** for the identity matrix. |
| number | number | The tenth value, which is affected by the rotation of the x, y, and z axes.| | m01 | number | Yes | The second value, which is affected by the rotation of the x, y, and z axes. |
| number | number | Scale factor along the z-axis. Defaults to **1** for the identity matrix. | | m02 | number | Yes | The third value, which is affected by the rotation of the x, y, and z axes. |
| number | number | Meaningless value. | | m03 | number | Yes | Meaningless value. |
| number | number | Translation distance along the x-axis. Defaults to **0** for the identity matrix. | | m10 | number | Yes | The fifth value, which is affected by the rotation of the x, y, and z axes. |
| number | number | Translation distance along the y-axis. Defaults to **0** for the identity matrix.| | m11 | number | Yes | Scale factor along the y-axis. Defaults to **1** for the identity matrix. |
| number | number | Translation distance along the z-axis. Defaults to **0** for the identity matrix.| | m12 | number | Yes | The seventh value, which is affected by the rotation of the x, y, and z axes. |
| number | number | Valid in homogeneous coordinates, presenting the perspective projection effect. | | m13 | number | Yes | Meaningless value. |
| m20 | number | Yes | The ninth value, which is affected by the rotation of the x, y, and z axes. |
| m21 | number | Yes | The tenth value, which is affected by the rotation of the x, y, and z axes. |
| m22 | number | Yes | Scale factor along the z-axis. Defaults to **1** for the identity matrix. |
| m23 | number | Yes | Meaningless value. |
| m30 | number | Yes | Translation value of the x-axis, in px. Defaults to **0** for the unit matrix.|
| m31 | number | Yes | Translation value of the y-axis, in px. The default value is **0** for the identity matrix.|
| m32 | number | Yes | Translation value of the z-axis, in px. The default value is **0** for the identity matrix.|
| m33 | number | Yes | Valid in homogeneous coordinates, presenting the perspective projection effect. |
**Example** **Example**
```js ```js
import matrix4 from '@ohos.matrix4'; import matrix4 from '@ohos.matrix4';
import componentUtils from '@ohos.componentUtils'; import componentUtils from '@ohos.arkui.componentUtils';
@Entry @Entry
@Component @Component
......
...@@ -100,7 +100,7 @@ Enumerates the types of Extension abilities. ...@@ -100,7 +100,7 @@ Enumerates the types of Extension abilities.
| Name| Value| Description| | Name| Value| Description|
|:----------------:|:---:|-----| |:----------------:|:---:|-----|
| FORM | 0 | [FormExtensionAbility](../../application-models/service-widget-overview.md): provides APIs for widget development.| | FORM | 0 | [FormExtensionAbility](../../application-models/service-widget-overview.md): provides APIs for widget development.|
| WORK_SCHEDULER | 1 | [WorkSchedulerExtensionAbility](../../task-management/work-scheduler.md): enables applications to execute non-real-time tasks when the system is idle. | | WORK_SCHEDULER | 1 | [WorkSchedulerExtensionAbility](../../task-management/work-scheduler.md): enables applications to execute non-real-time tasks when the system is idle.|
| INPUT_METHOD | 2 | [InputMethodExtensionAbility](js-apis-inputmethod-extension-ability.md): provides APIs for developing input method applications.| | INPUT_METHOD | 2 | [InputMethodExtensionAbility](js-apis-inputmethod-extension-ability.md): provides APIs for developing input method applications.|
| SERVICE | 3 | [ServiceExtensionAbility](../../application-models/serviceextensionability.md): enables applications to run in the background and provide services.| | SERVICE | 3 | [ServiceExtensionAbility](../../application-models/serviceextensionability.md): enables applications to run in the background and provide services.|
| ACCESSIBILITY | 4 | [AccessibilityExtensionAbility](js-apis-application-accessibilityExtensionAbility.md): provides accessibility for access to and operations on the UI.| | ACCESSIBILITY | 4 | [AccessibilityExtensionAbility](js-apis-application-accessibilityExtensionAbility.md): provides accessibility for access to and operations on the UI.|
...@@ -116,7 +116,6 @@ Enumerates the types of Extension abilities. ...@@ -116,7 +116,6 @@ Enumerates the types of Extension abilities.
| PRINT<sup>10+</sup> | 15 | PrintExtensionAbility: provides APIs for printing images. Printing documents is not supported yet.| | PRINT<sup>10+</sup> | 15 | PrintExtensionAbility: provides APIs for printing images. Printing documents is not supported yet.|
| PUSH<sup>10+</sup> | 17 | PushExtensionAbility: provides APIs for pushing scenario-specific messages. This ability is reserved.| | PUSH<sup>10+</sup> | 17 | PushExtensionAbility: provides APIs for pushing scenario-specific messages. This ability is reserved.|
| DRIVER<sup>10+</sup> | 18 | DriverExtensionAbility: provides APIs for the peripheral driver. This type of ability is not supported yet.| | DRIVER<sup>10+</sup> | 18 | DriverExtensionAbility: provides APIs for the peripheral driver. This type of ability is not supported yet.|
| APP_ACCOUNT_AUTHORIZATION<sup>10+</sup> | 19 | [AuthorizationExtensionAbility](js-apis-appAccount-authorizationExtensionAbility.md): provides APIs to process authorization requests for application accounts and allow account authorization from a third-party (relative to the operating system vendor) ecosystem platform.|
| UNSPECIFIED | 255 | No type is specified. It is used together with **queryExtensionAbilityInfo** to query all types of Extension abilities.| | UNSPECIFIED | 255 | No type is specified. It is used together with **queryExtensionAbilityInfo** to query all types of Extension abilities.|
......
...@@ -2687,7 +2687,7 @@ Represents detailed file information. Before calling any API of the **Stat()** c ...@@ -2687,7 +2687,7 @@ Represents detailed file information. Before calling any API of the **Stat()** c
| Name | Type | Readable | Writable | Description | | Name | Type | Readable | Writable | Description |
| ------ | ------ | ---- | ---- | ---------------------------------------- | | ------ | ------ | ---- | ---- | ---------------------------------------- |
| ino | number | Yes | No | File ID. Different files on the same device have different **ino**s.| | | ino | number | Yes | No | File ID. Different files on the same device have different **ino**s.| |
| mode | number | Yes | No | File permissions. The meaning of each bit is as follows:<br>- **0o400**: The owner has the read permission on a regular file or a directory entry.<br>- **0o200**: The owner has the permission to write a regular file or create and delete a directory entry.<br>- **0o100**: The owner has the permission to execute a regular file or search for the specified path in a directory.<br>- **0o040**: The user group has the read permission on a regular file or a directory entry.<br>- **0o020**: The user group has the permission to write a regular file or create and delete a directory entry.<br>- **0o010**: The user group has the permission to execute a regular file or search for the specified path in a directory.<br>- **0o004**: Other users have the permission to read a regular file or read a directory entry.<br>- **0o002**: Other users have the permission to write a regular file or create and delete a directory entry.<br>- **0o001**: Other users have the permission to execute a regular file or search for the specified path in a directory.| | mode | number | Yes | No | File permissions. The meaning of each bit is as follows:<br>**NOTE**<br>The following values are in octal format. The returned values are in decimal format. You need to convert the values.<br>- **0o400**: The owner has the permission to read a regular file or a directory entry.<br>- **0o200**: The owner has the permission to write a regular file or create and delete a directory entry.<br>- **0o100**: The owner has the permission to execute a regular file or search for the specified path in a directory.<br>- **0o040**: The user group has the permission to read a regular file or a directory entry.<br>- **0o020**: The user group has the permission to write a regular file or create and delete a directory entry.<br>- **0o010**: The user group has the permission to execute a regular file or search for the specified path in a directory.<br>- **0o004**: Other users have the permission to read a regular file or a directory entry.<br>- **0o002**: Other users have the permission to write a regular file or create and delete a directory entry.<br>- **0o001**: Other users have the permission to execute a regular file or search for the specified path in a directory.|
| uid | number | Yes | No | ID of the file owner.| | uid | number | Yes | No | ID of the file owner.|
| gid | number | Yes | No | ID of the user group of the file.| | gid | number | Yes | No | ID of the user group of the file.|
| size | number | Yes | No | File size, in bytes. This parameter is valid only for regular files. | | size | number | Yes | No | File size, in bytes. This parameter is valid only for regular files. |
......
...@@ -122,10 +122,10 @@ Defines parameters for an **AppEventInfo** object. ...@@ -122,10 +122,10 @@ Defines parameters for an **AppEventInfo** object.
| Name | Type | Mandatory| Description | | Name | Type | Mandatory| Description |
| --------- | ----------------------- | ---- | ------------------------------------------------------------ | | --------- | ----------------------- | ---- | ------------------------------------------------------------ |
| domain | string | Yes | Event domain. Event domain name, which is a string of up to 32 characters, including digits (0 to 9), letters (a to z), and underscores (\_). It must start with a lowercase letter and cannot end with an underscore (_).| | domain | string | Yes | Event domain. The value is a string of up to 32 characters, including digits (0 to 9), letters (a to z), and underscores (\_). It must start with a lowercase letter and cannot end with an underscore (_).|
| name | string | Yes | Event name. Event name, which is a string of up to 48 characters, including digits (0 to 9), letters (a to z), and underscores (\_). It must start with a lowercase letter and cannot end with an underscore (_).| | name | string | Yes | Event name. The value is a string of up to 48 characters, including digits (0 to 9), letters (a to z), and underscores (\_). It must start with a lowercase letter or dollar sign ($) and cannot end with an underscore (_).|
| eventType | [EventType](#eventtype) | Yes | Event type. | | eventType | [EventType](#eventtype) | Yes | Event type. |
| params | object | Yes | Event parameter object, which consists of a parameter name and a parameter value. The specifications are as follows:<br>- The parameter name is a string of up to 16 characters, including digits (0 to 9), letters (a to z), and underscores (\_). It must start with a lowercase letter and cannot end with an underscore (_).<br>- The parameter value can be a string, number, boolean, or array. If the parameter value is a string, its maximum length is 8*1024 characters. If this limit is exceeded, excess characters will be discarded. If the parameter value is a number, the value must be within the range of **Number.MIN_SAFE_INTEGER** to **Number.MAX_SAFE_INTEGER**. Otherwise, uncertain values may be generated. If the parameter value is an array, the elements in the array must be of the same type, which can only be string, number, or boolean. In addition, the number of elements must be less than 100. If this limit is exceeded, excess elements will be discarded.<br>- The maximum number of parameters is 32. If this limit is exceeded, excess parameters will be discarded.| | params | object | Yes | Event parameter object, which consists of a parameter name and a parameter value. The specifications are as follows:<br>- The parameter name is a string of up to 16 characters, including digits (0 to 9), letters (a to z), and underscores (\_). It must start with a lowercase letter or dollar sign ($) and cannot end with an underscore (_).<br>- The parameter value can be a string, number, boolean, or array. If the parameter value is a string, its maximum length is 8*1024 characters. If this limit is exceeded, excess characters will be discarded. If the parameter value is a number, the value must be within the range of **Number.MIN_SAFE_INTEGER** to **Number.MAX_SAFE_INTEGER**. Otherwise, uncertain values may be generated. If the parameter value is an array, the elements in the array must be of the same type, which can only be string, number, or boolean. In addition, the number of elements must be less than 100. If this limit is exceeded, excess elements will be discarded.<br>- The maximum number of parameters is 32. If this limit is exceeded, excess parameters will be discarded.|
## hiAppEvent.configure ## hiAppEvent.configure
...@@ -436,7 +436,7 @@ hiAppEvent.clearData(); ...@@ -436,7 +436,7 @@ hiAppEvent.clearData();
## EventType ## EventType
Enumerates event types. Enumerates the event types.
**System capability**: SystemCapability.HiviewDFX.HiAppEvent **System capability**: SystemCapability.HiviewDFX.HiAppEvent
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册