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

!19955 翻译完成 19322+19517:ArkTS卡片更新

Merge pull request !19955 from ester.zhou/TR-18904
......@@ -32,7 +32,7 @@ Widget-related configuration includes **FormExtensionAbility** configuration and
}
```
2. Configure the widget configuration information. In the **metadata** configuration item of FormExtensionAbility, you can specify the resource index of specific configuration information of the widget. For example, if resource is set to **$profile:form_config**, **form_config.json** in the **resources/base/profile/** directory of the development view is used as the profile configuration file of the widget. The following table describes the internal field structure.
2. Configure the widget configuration information. In the **metadata** configuration item of FormExtensionAbility, you can specify the resource index of specific configuration information of the widget. For example, if **resource** is set to **$profile:form_config**, **form_config.json** in the **resources/base/profile/** directory of the development view is used as the profile configuration file of the widget. The following table describes the internal structure of the profile configuration file.
**Table 1** form_config.json file
......@@ -47,8 +47,8 @@ Widget-related configuration includes **FormExtensionAbility** configuration and
| colorMode | Color mode of the widget.<br>- **auto**: auto-adaptive color mode<br>- **dark**: dark color mode<br>- **light**: light color mode| String| Yes (initial value: **auto**)|
| supportDimensions | Grid styles supported by the widget.<br>- **1 * 2**: indicates a grid with one row and two columns.<br>- **2 * 2**: indicates a grid with two rows and two columns.<br>- **2 * 4**: indicates a grid with two rows and four columns.<br>- **4 * 4**: indicates a grid with four rows and four columns.| String array| No|
| defaultDimension | Default grid style of the widget. The value must be available in the **supportDimensions** array of the widget.| String| No|
| updateEnabled | Whether the widget can be updated periodically.<br>- **true**: The widget can be updated at a specified interval (**updateDuration**) or at the scheduled time (**scheduledUpdateTime**). **updateDuration** takes precedence over **scheduledUpdateTime**.<br>- **false**: The widget cannot be updated periodically.| Boolean| No|
| scheduledUpdateTime | Scheduled time to update the widget. The value is in 24-hour format and accurate to minute.<br>**NOTE**<br>**updateDuration** takes precedence over **scheduledUpdateTime**. If both are specified, the value specified by **updateDuration** is used.| String| Yes (initial value: The widget cannot be updated periodically.)|
| updateEnabled | Whether the widget can be updated periodically.<br>- **true**: The widget can be updated at a specified interval (**updateDuration**) or at the scheduled time (**scheduledUpdateTime**). **updateDuration** takes precedence over **scheduledUpdateTime**. If both are specified, the value specified by **updateDuration** is used.<br>- **false**: The widget cannot be updated periodically.| Boolean| No|
| scheduledUpdateTime | Scheduled time to update the widget. The value is in 24-hour format and accurate to minute.<br>**NOTE**<br>**updateDuration** takes precedence over **scheduledUpdateTime**. If both are specified, the value specified by **updateDuration** is used.| String| Yes (initial value: The widget is not updated at the scheduled time.)|
| updateDuration | Interval to update the widget. The value is a natural number, in the unit of 30 minutes.<br>If the value is **0**, this field does not take effect.<br>If the value is a positive integer *N*, the interval is calculated by multiplying *N* and 30 minutes.<br>**NOTE**<br>**updateDuration** takes precedence over **scheduledUpdateTime**. If both are specified, the value specified by **updateDuration** is used.| Number| Yes (initial value: **0**)|
| formConfigAbility | Link to a specific page of the application. The value is a URI.| String| Yes (initial value: left empty)|
| formVisibleNotify | Whether the widget is allowed to use the widget visibility notification.| String| Yes (initial value: left empty)|
......
......@@ -3,9 +3,9 @@
To create an ArkTS widget in an existing application project, perform the following steps:
1. Create a widget.
![WidgetProjectCreate1](figures/WidgetProjectCreate1.png)
2. Select a widget template based on the actual service scenario.
![WidgetProjectCreate2](figures/WidgetProjectCreate2.png)
......@@ -14,6 +14,6 @@ To create an ArkTS widget in an existing application project, perform the follow
![WidgetProjectCreate3](figures/WidgetProjectCreate3.png)
After an ArkTS widget is created, the following widget-related files are added to the project directory: **EntryFormAbility.ts** (widget lifecycle management file), **WidgetCard.ets** (widget page file), and **form_config.json** (widget configuration file).
After an ArkTS widget is created, the following widget-related files are automatically added to the project directory: **EntryFormAbility.ts** (widget lifecycle management file), **WidgetCard.ets** (widget page file), and **form_config.json** (widget configuration file).
![WidgetProjectView](figures/WidgetProjectView.png)
![WidgetProjectView](figures/WidgetProjectView.png)
\ No newline at end of file
# Launching a UIAbility in the Background Through the call Event
There may be cases you want to provide in a widget access to features available in your application when it is running in the foreground, for example, the play, pause, and stop buttons in a music application widget. This is where the **call** capability of the **postCardAction** API comes in handy. This capability, when used in a widget, can start the specified UIAbility of the widget provider in the background. It also allows the widget to call the specified method of the application and transfer data so that the application, while in the background, can behave accordingly in response to touching of the buttons on the widget.
There may be cases you want to provide in a widget access to features available in your application running in the foreground, for example, the play, pause, and stop buttons in a music application widget. This is where the **call** capability of the **postCardAction** API comes in handy. This capability, when used in a widget, can start the specified UIAbility of the widget provider in the background. It also allows the widget to call the specified method of the application and transfer data so that the application, while in the background, can behave accordingly in response to touching of the buttons on the widget.
Generally, buttons are used to trigger the **call** event. Below is an example.
Typically, the call event is triggered for touching of buttons. Below is an example.
- In this example, two buttons are laid out on the widget page. When one button is clicked, the **postCardAction** API is called to send a **call** event to the target UIAbility. Note that the **method** parameter in the API indicates the method to call in the target UIAbility. It is mandatory and of the string type.
- In this example, two buttons are laid out on the widget page. When one button is clicked, the **postCardAction** API is called to send a call event to the target UIAbility. Note that the **method** parameter in the API indicates the method to call in the target UIAbility. It is mandatory and of the string type.
```ts
@Entry
......@@ -37,7 +37,7 @@ Generally, buttons are used to trigger the **call** event. Below is an example.
'abilityName': 'EntryAbility', // Only the UIAbility of the current application is allowed.
'params': {
'method': 'funB', // Set the name of the method to call in the EntryAbility.
'num': 1 // Set other parameters to be transferred.
'num': 1 // Set other parameters to be passed in.
}
});
})
......@@ -48,34 +48,36 @@ Generally, buttons are used to trigger the **call** event. Below is an example.
}
```
- The UIAbility receives the **call** event and obtains the transferred parameters. It then executes the target method specified by the **method** parameter. Other data can be obtained in readString mode. Listen for the method required by the **call** event in the **onCreate** callback of the UIAbility.
- The UIAbility receives the call event and obtains the transferred parameters. It then executes the target method specified by the **method** parameter. Other data can be obtained in readString mode. Listen for the method required by the call event in the **onCreate** callback of the UIAbility.
```ts
import UIAbility from '@ohos.app.ability.UIAbility';
function FunACall(data) {
// Obtain all parameters transferred in the call event.
// Obtain all parameters passed in the call event.
console.info('FunACall param:' + JSON.stringify(data.readString()));
return null;
}
function FunBCall(data) {
console.info('FunACall param:' + JSON.stringify(data.readString()));
console.info('FunBCall param:' + JSON.stringify(data.readString()));
return null;
}
export default class CameraAbility extends UIAbility {
// If the UIAbility is started for the first time, the onCreate lifecycle callback is triggered after the call event is received.
// If the UIAbility is started for the first time, onCreate is triggered afte the call event is received.
onCreate(want, launchParam) {
try {
// Listen for the method required by the call event.
this.callee.on('funA', FunACall);
this.callee.on('funB', FunBCall);
} catch (error) {
} catch (err) {
console.error(`Failed to register callee on. Cause: ${JSON.stringify(err)}`);
}
}
...
// Deregister the listener when the process exits.
onDestroy() {
try {
......
......@@ -5,7 +5,7 @@ On the widget page, the **postCardAction** API can be used to trigger a router o
## Updating Widget Content Through the router Event
- On the widget page, register the **onClick** event callback of the button and call the **postCardAction** API in the callback to trigger the **router** event to the FormExtensionAbility.
- On the widget page, register the **onClick** event callback of the button and call the **postCardAction** API in the callback to trigger the router event to the FormExtensionAbility.
```ts
let storage = new LocalStorage();
......@@ -45,7 +45,7 @@ On the widget page, the **postCardAction** API can be used to trigger a router o
import formInfo from '@ohos.app.form.formInfo';
export default class EntryAbility extends UIAbility {
// If the UIAbility is started for the first time, the onCreate lifecycle callback is triggered after the router event is received.
// If the UIAbility is started for the first time, onCreate is triggered after the router event is received.
onCreate(want, launchParam) {
console.info('Want:' + JSON.stringify(want));
if (want.parameters[formInfo.FormParam.IDENTITY_KEY] !== undefined) {
......@@ -63,7 +63,7 @@ On the widget page, the **postCardAction** API can be used to trigger a router o
})
}
}
// If the UIAbility is running in the background, the onNewWant lifecycle callback is triggered after the router event is received.
// If the UIAbility is running in the background, onNewWant is triggered after the router event is received.
onNewWant(want, launchParam) {
console.info('onNewWant Want:' + JSON.stringify(want));
if (want.parameters[formInfo.FormParam.IDENTITY_KEY] !== undefined) {
......@@ -88,7 +88,7 @@ On the widget page, the **postCardAction** API can be used to trigger a router o
## Updating Widget Content Through the call Event
- When using the **call** event of the **postCardAction** API, the value of **formId** must be updated in the **onAddForm** callback of the FormExtensionAbility.
- When using the call event of the **postCardAction** API, the value of **formId** must be updated in the **onAddForm** callback of the FormExtensionAbility.
```ts
import formBindingData from '@ohos.app.form.formBindingData';
......@@ -142,13 +142,12 @@ On the widget page, the **postCardAction** API can be used to trigger a router o
}
```
- Listen for the method required by the **call** event in the **onCreate** callback of the UIAbility, and then call the [updateForm](../reference/apis/js-apis-app-form-formProvider.md#updateform) API in the corresponding method to update the widget.
- Listen for the method required by the call event in the **onCreate** callback of the UIAbility, and then call the [updateForm](../reference/apis/js-apis-app-form-formProvider.md#updateform) API in the corresponding method to update the widget.
```ts
import UIAbility from '@ohos.app.ability.UIAbility';
import formBindingData from '@ohos.app.form.formBindingData';
import formProvider from '@ohos.app.form.formProvider';
import formInfo from '@ohos.app.form.formInfo';
const MSG_SEND_METHOD: string = 'funA';
......@@ -173,7 +172,7 @@ On the widget page, the **postCardAction** API can be used to trigger a router o
return null;
}
export default class EntryAbility extends UIAbility {
// If the UIAbility is started for the first time, the onCreate lifecycle callback is triggered after the call event is received.
// If the UIAbility is started for the first time, onCreate is triggered after the call event is received.
onCreate(want, launchParam) {
console.info('Want:' + JSON.stringify(want));
try {
......
# Widget Data Interaction
The ArkTS widget framework provides the **updateForm()** and **requestForm()** APIs to proactively trigger widget updates.
![WidgetLocalStorageProp](figures/WidgetLocalStorageProp.png)
| API| System Capability| Constraints|
| -------- | -------- | -------- |
| updateForm | No| 1. Invoked by the provider.<br>2. Allows only the widget provider to update its own widgets. It cannot be used to update widgets by other providers.|
| requestForm | Yes| 1. Invoked by the host.<br>2. Allows only the widget host to update the widgets added to it. It cannot be used to update widgets added to other hosts.|
| updateForm | No| 1. Invoked by the widget provider.<br>2. Allows only the widget provider to update its own widgets.|
| requestForm | Yes| 1. Invoked by the widget host.<br>2. Allows only the widget host to update the widgets added to it.|
The following describes the typical use cases of widget updates:
The following are the typical use cases of widget updates:
- [Configuring a Widget to Update Periodically](arkts-ui-widget-update-by-time.md)
- [Updating Widget Content Through a Proxy](arkts-ui-widget-update-by-proxy.md)
- [Updating Local and Online Images](arkts-ui-widget-image-update.md)
- [Updating Widget Content by State](arkts-ui-widget-update-by-status.md)
- [Updating Widget Content by Widget Host (for System Applications Only)](arkts-ui-widget-content-update.md)
# Widget Page Capability Overview
You can leverage the ArkUI declarative paradigm to develop ArkTS widget pages. The following widget pages are automatically generated by a DevEco Studio template. You can adjust the pages based on the real-world service scenarios.
![WidgetPreviewPage](figures/WidgetPreviewPage.png)
ArkTS widgets have full capabilities of JS widgets, with added animation and custom drawing capabilities plus partial support for components, events, animations, data management, and state management capabilities of the [declarative paradigm](../reference/arkui-ts/ts-components-summary.md). For details, see [Page Capabilities Supported by ArkTS Widgets](#page-capabilities-supported-by-arkts-widgets).
## Page Capabilities Supported by ArkTS Widgets
ArkTS widgets have full capabilities of JS widgets, with added animation and custom drawing capabilities plus partial support for components, events, animations, data management, and state management capabilities of the [declarative paradigm](../reference/arkui-ts/ts-components-summary.md).
For details about the page capabilities supported by ArkTS widgets, see [Learning ArkTS](../quick-start/arkts-create-custom-components.md) and [ArkTS-based Declarative Development Paradigm](../reference/arkui-ts/ts-components-summary.md).
For details about the capabilities supported by ArkTS widgets, see [Learning ArkTS](../quick-start/arkts-create-custom-components.md) and [ArkTS-based Declarative Development Paradigm](../reference/arkui-ts/ts-components-summary.md).
Only the APIs marked with "supported in ArkTS widgets" can be used for ArkTS widgets. Pay special attention to the capability differences with applications.
Only the APIs marked with "supported in ArkTS widgets" can be used for ArkTS widgets. Pay special attention to the differences from applications.
For example, the following description indicates that the @Component decorator can be used in ArkTS widgets.
![WidgetSupportApi](figures/WidgetSupportApi.png)
![WidgetSupportApi](figures/WidgetSupportApi.png)
\ No newline at end of file
# Updating Widget Content Through a Proxy
A widget can be updated through a proxy – a system application that has data sharing enabled – when the widget provider is not running.
## Implementation Principles
**Figure 1** Updating widget content through a proxy
![UpdateWidgetByProxyPrinciple](figures/UpdateWidgetByProxyPrinciple.png)
Compared with the [implementation of the ArkTS widget](../application-models/arkts-ui-widget-working-principles.md#implementation-principles) alone, updating through a proxy involves the data management service and data provider.
- Data management service: provides a mechanism for data sharing among multiple applications.
- Data provider: must be a system application that has data sharing enabled. The shared data is identified through the defined **key** + **subscriberId** combination.
Processing flow of the widget provider (indicated by the blue arrows in the figure):
1. The widget provider sets the **dataProxyEnabled** field to **true** in the **form_config.json** file to enable the update-through-proxy feature.
> **NOTE**
>
> After the update-through-proxy feature is enabled, the settings for [updating periodically](../application-models/arkts-ui-widget-update-by-time.md) do not work.
2. In the [onAddForm](../reference/apis/js-apis-app-form-formExtensionAbility.md#onaddform) callback, the widget provider returns the **key** + **subscriberId** combination defined by the data provider to the Widget Manager.
3. Widget Manager parses the subscription information of the widget provider and registers a subscription instance with the data management service.
Processing flow of the widget update proxy (indicated by the red arrows in the figure):
1. The data provider uses the **key** + **subscriberId** combination as the data ID to store data to the database.
2. The data management service detects the change in the database and publishes the new data to all currently registered subscription instances.
3. The Widget Manager parses data from the subscription instance and sends the data to the widget rendering service.
4. The widget rendering service runs the widget page code **widgets.abc**, renders based on the new data, and sends the rendered data to the widget component (../reference/arkui-ts/ts-basic-components-formcomponent.md) corresponding to the widget host.
There are two types of shared data provided by the data provider:
- Ephemeral data: data that exists only for a specific period of time and can be subscribed to by system and non-system applications alike.
- Persistent data: data that persists over time and can only be subscribed to by system applications.
The update-through-proxy configuration varies by the type of shared data.
## Widget Provider Development (Ephemeral Data)
- Set the **dataProxyEnabled** field to **true** in the **form_config.json** file to enable the update-through-proxy feature.
```json
{
"forms": [
{
"name": "widget",
"description": "This is a service widget.",
"src": "./ets/widget/pages/WidgetCard.ets",
"uiSyntax": "arkts",
"window": {
"designWidth": 720,
"autoDesignWidth": true
},
"colorMode": "auto",
"isDefault": true,
"updateEnabled": true,
"scheduledUpdateTime": "10:30",
"defaultDimension": "2*2",
"supportDimensions": ["2*2"],
"dataProxyEnabled": true // Enable the update-through-proxy feature.
}
]
}
```
- Configure the subscription information [proxies](../reference/apis/js-apis-app-form-formBindingData.md#proxydata) in the [onAddForm](../reference/apis/js-apis-app-form-formExtensionAbility.md#onaddform) callback and return the information to the Widget Manager through [formBinding](../reference/apis/js-apis-app-form-formBindingData.md#formbindingdata). In this example, **key** is set to **detail** and **subscriberId** is set to **11**.
> **NOTE**
>
> The value of **key** can be a URI or a simple string. The default value of **subscriberId** is the value of **formId**. The actual value depends on the definition of the data provider.
```ts
import formBindingData from '@ohos.app.form.formBindingData';
let dataShareHelper;
onAddForm(want) {
let formData = {};
let proxies = [
{
"key": "detail",
"subscriberId": "11"
}
]
let formBinding = formBindingData.createFormBindingData(formData);
formBinding["proxies"] = proxies;
return formBinding;
}
```
- In the widget page code file **widgets.abc**, use the variable in LocalStorage to obtain the subscribed data. In this example, the subscribed data is obtained through **'detail'** and displayed in the **\<Text>** component.
```ts
let storage = new LocalStorage();
@Entry(storage)
@Component
struct Index {
@LocalStorageProp('detail') detail: string = 'Loading...';
build() {
Row() {
Column() {
Text(this.detail)
.fontSize('12vp')
.textAlign(TextAlign.Center)
.width('100%')
.height('15%')
}
.width('100%')
}
.height('100%')
}
}
```
## Widget Provider Development (Persistent Data; for System Applications Only)
- Set the **dataProxyEnabled** field to **true** in the **form_config.json** file to enable the update-through-proxy feature.
```json
{
"forms": [
{
"name": "widget",
"description": "This is a service widget.",
"src": "./ets/widget/pages/WidgetCard.ets",
"uiSyntax": "arkts",
"window": {
"designWidth": 720,
"autoDesignWidth": true
},
"colorMode": "auto",
"isDefault": true,
"updateEnabled": true,
"scheduledUpdateTime": "10:30",
"defaultDimension": "2*2",
"supportDimensions": ["2*2"],
"dataProxyEnabled": true // Enable the update-through-proxy feature.
}
]
}
```
- Add a subscription template ([addTemplate]([../reference/apis/js-apis-data-dataShare.md#addtemplate10)) to the [onAddForm](../reference/apis/js-apis-app-form-formExtensionAbility.md#onaddform) callback and use the template predicates to notify the database of the subscribed data conditions. Then, configure the subscription information [proxies](../reference/apis/js-apis-app-form-formBindingData.md#proxydata) and return it to the Widget Manager through [formBinding](../reference/apis/js-apis-app-form-formBindingData.md#formbindingdata). In the example, the predicate is set to **"list": "select type from TBL00 limit 0,1"**, indicating that the first data record in the **type** column is obtained from the **TBL00** database. The data is returned to the widget page code file **widgets.abc** in {"list":[{"type":"value0"}]} format.
> **NOTE**
>
> - The value of **key** is a URI, which depends on the definition of the data release party.
> - The value of **subscriberId** can be customized. Ensure that the value of **subscriberId** in **addTemplate** is the same as that of **proxies.subscriberId**.
```ts
import formBindingData from '@ohos.app.form.formBindingData';
import FormExtensionAbility from '@ohos.app.form.FormExtensionAbility';
import dataShare from '@ohos.data.dataShare'
let dataShareHelper;
onAddForm(want) {
let template = {
predicates : {
"list" : "select type from TBL00 limit 0,1"
},
scheduler: ""
}
let subscriberId = "111";
dataShare.createDataShareHelper(this.context, "datashareproxy://com.example.myapplication", {isProxy : true}).then((data) => {
dataShareHelper = data;
dataShareHelper.addTemplate("datashareproxy://com.example.myapplication/test", subscriberId, template);
})
let formData = {};
let proxies = [
{
"key": "datashareproxy://com.example.myapplication/test",
"subscriberId": subscriberId
}
]
let formBinding = formBindingData.createFormBindingData(formData);
formBinding["proxies"] = proxies;
return formBinding;
}
```
- In the widget page code file **widgets.abc**, use the variable in LocalStorage to obtain the subscribed data. In the example, the subscribed data is obtained through **'list'**, and the value of the first element is displayed on the **\<Text>** component.
```ts
let storage = new LocalStorage();
@Entry(storage)
@Component
struct WidgetCard {
readonly ACTION_TYPE: string = 'router';
readonly ABILITY_NAME: string = 'EntryAbility';
readonly MESSAGE: string = 'add detail';
readonly FULL_WIDTH_PERCENT: string = '100%';
readonly FULL_HEIGHT_PERCENT: string = '100%';
@LocalStorageProp('list') list: Array<object> = [{"type": "a"}];
build() {
Row() {
Column() {
Text((this.list[0]["type"]))
.fontSize($r('app.float.font_size'))
}
.width(this.FULL_WIDTH_PERCENT)
}
.height(this.FULL_HEIGHT_PERCENT)
.onClick(() => {
postCardAction(this, {
"action": this.ACTION_TYPE,
"abilityName": this.ABILITY_NAME,
"params": {
"message": this.MESSAGE
}
})
})
}
}
```
## Data Provider Development
For details, see [Data Management](../database/data-mgmt-overview.md).
<!--no_check-->
\ No newline at end of file
......@@ -5,12 +5,12 @@ Before configuring a widget to update periodically, enable the periodic update f
The widget framework provides the following modes of updating widgets periodically:
- Set the update interval: The widget will be updated at the specified interval by calling [onUpdateForm](../reference/apis/js-apis-app-form-formExtensionAbility.md#onupdateform). You can specify the interval by setting the [updateDuration](arkts-ui-widget-configuration.md) field in the **form_config.json** file. For example, you can configure the widget to update once an hour.
- Setting the update interval: The widget will be updated at the specified interval by calling [onUpdateForm](../reference/apis/js-apis-app-form-formExtensionAbility.md#onupdateform). You can specify the interval by setting the [updateDuration](arkts-ui-widget-configuration.md) field in the **form_config.json** file. For example, you can configure the widget to update once an hour.
> **NOTE**
>
> **updateDuration** takes precedence over **scheduledUpdateTime**. If both are specified, the value specified by **updateDuration** is used.
```json
{
"forms": [
......@@ -26,22 +26,22 @@ The widget framework provides the following modes of updating widgets periodical
"colorMode": "auto",
"isDefault": true,
"updateEnabled": true, // Enable the periodic update feature.
"scheduledUpdateTime": "10:30",
"updateDuration": 2, // Set the interval to update the widget. The value is a natural number, in the unit of 30 minutes.
"scheduledUpdateTime": "10:30",
"updateDuration": 2, // Set the update interval. The value is a natural number, in the unit of 30 minutes.
"defaultDimension": "2*2",
"supportDimensions": ["2*2"]
}
]
}
```
- Set the scheduled update time: The widget will be updated at the scheduled time every day. You can specify the time by setting the [scheduledUpdateTime](arkts-ui-widget-configuration.md) field in the **form_config.json** file. For example, you can configure the widget to update at 10:30 a.m. every day.
- Setting the scheduled update time: The widget will be updated at the scheduled time every day. You can specify the time by setting the [scheduledUpdateTime](arkts-ui-widget-configuration.md) field in the **form_config.json** file. For example, you can configure the widget to update at 10:30 a.m. every day.
> **NOTE**
>
> **updateDuration** takes precedence over **scheduledUpdateTime**. For the **scheduledUpdateTime** settings to take effect, set **updateDuration** to **0**.
```json
{
"forms": [
......@@ -65,12 +65,12 @@ The widget framework provides the following modes of updating widgets periodical
]
}
```
- Set the next update time: The widget will be updated next time at the specified time. You can specify the time by calling the [setFormNextRefreshTime()](../reference/apis/js-apis-app-form-formProvider.md#setformnextrefreshtime) API. The minimum update interval is 5 minutes. For example, you can configure the widget to update within 5 minutes after the API is called.
- Setting the next update time: The widget will be updated next time at the specified time. You can specify the time by calling the [setFormNextRefreshTime()](../reference/apis/js-apis-app-form-formProvider.md#setformnextrefreshtime) API. The minimum update interval is 5 minutes. For example, you can configure the widget to update within 5 minutes after the API is called.
```ts
import formProvider from '@ohos.app.form.formProvider';
let formId = '123456789'; // Use the actual widget ID in real-world scenarios.
try {
// Configure the widget to update in 5 minutes.
......@@ -88,12 +88,10 @@ The widget framework provides the following modes of updating widgets periodical
```
When periodic update is triggered, the system calls the [onUpdateForm()](../reference/apis/js-apis-app-form-formExtensionAbility.md#onupdateform) lifecycle callback of the FormExtensionAbility. In the callback, [updateForm()](../reference/apis/js-apis-app-form-formProvider.md#updateform) can be used to update the widget by the provider. For details about how to use **onUpdateForm()**, see [Updating Widget Content Through FormExtensionAbility](arkts-ui-widget-event-formextensionability.md).
When periodic update is triggered, the system calls the [onUpdateForm()](../reference/apis/js-apis-app-form-formExtensionAbility.md#onupdateform) lifecycle callback of the FormExtensionAbility. In the callback, [updateForm()](../reference/apis/js-apis-app-form-formProvider.md#updateform) can be used to update the widget. For details about how to use **onUpdateForm()**, see [Updating Widget Content Through FormExtensionAbility](arkts-ui-widget-event-formextensionability.md).
> **NOTE**
> 1. Each widget can be updated at the specified interval for a maximum of 50 times every day, including updates triggered by setting [updateDuration](arkts-ui-widget-configuration.md) or calling [setFormNextRefreshTime()](../reference/apis/js-apis-app-form-formProvider.md#setformnextrefreshtime). When the limit is reached, the widget cannot be updated in this mode again. The number of update times is reset at 00:00 every day.
>
> 2. The same timer is used for timing updates at the specified interval. Therefore, the first scheduled update of widgets may have a maximum deviation of 30 minutes. For example, the first widget A (updated every half an hour) is added at 03:20. The timer starts and triggers an update every half an hour. The second widget B (updated every half an hour) is added at 03:40. When the timer event is triggered at 03:50, widget A is updated, and widget B will be updated at 04:20 next time.
>
> 3. Updates at the specified interval and updates at the scheduled time are triggered only when the screen is on. When the screen is off, the update action is merely recorded. When the screen is on, the update action is performed.
> - Each widget can be updated at the specified interval for a maximum of 50 times every day, including updates triggered by setting [updateDuration](arkts-ui-widget-configuration.md) or calling [setFormNextRefreshTime()](../reference/apis/js-apis-app-form-formProvider.md#setformnextrefreshtime). When the limit is reached, the widget cannot be updated in this mode again. The number of update times is reset at 00:00 every day.
>- A single timer is used for timing updates at the specified interval. Therefore, if a widget is configured to update at scheduled intervals, the first scheduled update may have a maximum deviation of 30 minutes. For example, if widget A (updated every half an hour) is added at 03:20 and widget B (also updated every half an hour) is added at 03:40, the first update of widget B has a deviation of 10 minutes to the expected time: The timer starts at 03:20 when widget A is added, triggers an update for widget A at 03:50, and triggers another update for widget B at 04:20 (instead of 04:10 as expected).
> - Updates at the specified interval and updates at the scheduled time are triggered only when the screen is on. The update action is merely recorded when the screen is off and is performed once the screen is on.
......@@ -16,13 +16,13 @@ The widget host consists of the following modules:
- Widget usage: provides operations such as creating, deleting, or updating a widget.
- Communication adapter: provided by the OpenHarmony SDK for communication with the Widget Manager. It sends widget-related operations to the Widget Manager.
- Communication adapter: provided by the SDK for communication with the Widget Manager. It sends widget-related operations to the Widget Manager.
The Widget Manager consists of the following modules:
- Periodic updater: starts a scheduled task based on the update policy to periodically update a widget after it is added to the Widget Manager.
- Cache manager: caches view information of a widget after it is added to the Widget Manager to directly return the cached data when the widget is obtained next time. This reduces the latency greatly.
- Cache manager: caches view information of a widget after it is added to the Widget Manager. This enables the cached data to be directly returned when the widget is obtained next time, greatly reducing the latency.
- Lifecycle manager: suspends update when a widget is switched to the background or is blocked, and updates and/or clears widget data during upgrade and deletion.
......@@ -36,9 +36,10 @@ The widget provider consists of the following modules:
- Instance manager: implemented by the widget provider developer for persistent management of widget instances allocated by the Widget Manager.
- Communication adapter: provided by the OpenHarmony SDK for communication with the Widget Manager. It pushes update data to the Widget Manager.
- Communication adapter: provided by the SDK for communication with the Widget Manager. It pushes update data to the Widget Manager.
> **NOTE**
>
> You only need to develop the widget provider. The system automatically handles the work of the widget host and Widget Manager.
......@@ -48,14 +49,14 @@ The **FormExtensionAbility** class has the following APIs. For details, see [For
| Name| Description|
| -------- | -------- |
| onAddForm(want: Want): formBindingData.FormBindingData | Called to notify the widget provider that a widget has been created.|
| onCastToNormalForm(formId: string): void | Called to notify the widget provider that a temporary widget has been converted to a normal one.|
| onUpdateForm(formId: string): void | Called to notify the widget provider that a widget has been updated.|
| onChangeFormVisibility(newStatus: { [key: string]: number }): void | Called to notify the widget provider of the change in widget visibility.|
| onFormEvent(formId: string, message: string): void | Called to instruct the widget provider to receive and process a widget event.|
| onRemoveForm(formId: string): void | Called to notify the widget provider that a widget has been destroyed.|
| onConfigurationUpdate(config: Configuration): void | Called when the configuration of the environment where the widget is running is updated.|
| onShareForm?(formId: string): { [key: string]: any } | Called by the widget provider to receive shared widget data.|
| onAddForm(want: Want): formBindingData.FormBindingData | Called to notify the widget provider that a widget is being created.|
| onCastToNormalForm(formId: string): void | Called to notify the widget provider that a temporary widget is being converted to a normal one.|
| onUpdateForm(formId: string): void | Called to notify the widget provider that a widget is being updated.|
| onChangeFormVisibility(newStatus: { [key: string]: number }): void | Called to notify the widget provider that the widget visibility status is being changed.|
| onFormEvent(formId: string, message: string): void | Called to instruct the widget provider to process a widget event.|
| onRemoveForm(formId: string): void | Called to notify the widget provider that a widget is being destroyed.|
| onConfigurationUpdate(config: Configuration): void | Called when the configuration of the environment where the widget is running is being updated.|
| onShareForm?(formId: string): { [key: string]: any } | Called to notify the widget provider that the widget host is sharing the widget data.|
The **FormProvider** class has the following APIs. For details, see [FormProvider](../reference/apis/js-apis-app-form-formProvider.md).
......@@ -79,11 +80,11 @@ The widget provider development based on the [stage model](stage-model-developme
- [Creating a FormExtensionAbility Instance](#creating-a-formextensionability-instance): Develop the lifecycle callback functions of FormExtensionAbility.
- [Configuring the Widget Configuration Files](#configuring-the-widget-configuration-files): Configure the application configuration file **module.json5** and profile configuration file.
- [Configuring the Widget Configuration File](#configuring-the-widget-configuration-file): Configure the application configuration file **module.json5** and profile configuration file.
- [Persistently Storing Widget Data](#persistently-storing-widget-data): This operation is a form of widget data exchange.
- [Persistently Storing Widget Data](#persistently-storing-widget-data): Manage widget data persistence.
- [Updating Widget Data](#updating-widget-data): Call **updateForm()** to update the information displayed on a widget.
- [Updating Widget Data](#updating-widget-data): Call **updateForm()** to update the information displayed in a widget.
- [Developing the Widget UI Page](#developing-the-widget-ui-page): Use HML+CSS+JSON to develop a JS widget UI page.
......@@ -92,7 +93,7 @@ The widget provider development based on the [stage model](stage-model-developme
### Creating a FormExtensionAbility Instance
To create a widget in the stage model, implement the lifecycle callbacks of **FormExtensionAbility**. Generate a widget template by referring to [Developing a Service Widget](https://developer.harmonyos.com/en/docs/documentation/doc-guides/ohos-development-service-widget-0000001263280425).
To create a widget in the stage model, you need to implement the lifecycle callbacks of FormExtensionAbility. Generate a widget template and then perform the following:
1. Import related modules to **EntryFormAbility.ts**.
......@@ -102,7 +103,7 @@ To create a widget in the stage model, implement the lifecycle callbacks of **Fo
import formBindingData from '@ohos.app.form.formBindingData';
import formInfo from '@ohos.app.form.formInfo';
import formProvider from '@ohos.app.form.formProvider';
import dataStorage from '@ohos.data.storage';
import dataPreferences from '@ohos.data.preferences';
```
2. Implement the FormExtension lifecycle callbacks in **EntryFormAbility.ts**.
......@@ -121,7 +122,7 @@ To create a widget in the stage model, implement the lifecycle callbacks of **Fo
return formData;
}
onCastToNormalForm(formId) {
// Called when the widget host converts the temporary widget into a normal one. The widget provider should do something to respond to the conversion.
// Called when a temporary widget is being converted into a normal one. The widget provider should respond to the conversion.
console.info('[EntryFormAbility] onCastToNormalForm');
}
onUpdateForm(formId) {
......@@ -158,6 +159,7 @@ To create a widget in the stage model, implement the lifecycle callbacks of **Fo
```
> **NOTE**
>
> FormExtensionAbility cannot reside in the background. Therefore, continuous tasks cannot be processed in the widget lifecycle callbacks.
......@@ -190,7 +192,7 @@ To create a widget in the stage model, implement the lifecycle callbacks of **Fo
}
```
2. Configure the widget configuration information. In the **metadata** configuration item of FormExtensionAbility, you can specify the resource index of specific configuration information of the widget. For example, if resource is set to **$profile:form_config**, **form_config.json** in the **resources/base/profile/** directory of the development view is used as the profile configuration file of the widget. The following table describes the internal field structure.
2. Configure the widget configuration information. In the **metadata** configuration item of FormExtensionAbility, you can specify the resource index of specific configuration information of the widget. For example, if **resource** is set to **$profile:form_config**, **form_config.json** in the **resources/base/profile/** directory of the development view is used as the profile configuration file of the widget. The following table describes the internal structure of the profile configuration file.
**Table 1** Widget profile configuration file
......@@ -204,7 +206,7 @@ To create a widget in the stage model, implement the lifecycle callbacks of **Fo
| colorMode | Color mode of the widget.<br>- **auto**: auto-adaptive color mode<br>- **dark**: dark color mode<br>- **light**: light color mode| String| Yes (initial value: **auto**)|
| supportDimensions | Grid styles supported by the widget.<br>- **1 * 2**: indicates a grid with one row and two columns.<br>- **2 * 2**: indicates a grid with two rows and two columns.<br>- **2 * 4**: indicates a grid with two rows and four columns.<br>- **4 * 4**: indicates a grid with four rows and four columns.| String array| No|
| defaultDimension | Default grid style of the widget. The value must be available in the **supportDimensions** array of the widget.| String| No|
| updateEnabled | Whether the widget can be updated periodically.<br>- **true**: The widget can be updated at a specified interval (**updateDuration**) or at the scheduled time (**scheduledUpdateTime**). **updateDuration** takes precedence over **scheduledUpdateTime**.<br>- **false**: The widget cannot be updated periodically.| Boolean| No|
| updateEnabled | Whether the widget can be updated periodically.<br>- **true**: The widget can be updated at a specified interval (**updateDuration**) or at the scheduled time (**scheduledUpdateTime**). **updateDuration** takes precedence over **scheduledUpdateTime**. If both are specified, the value specified by **updateDuration** is used.<br>- **false**: The widget cannot be updated periodically.| Boolean| No|
| scheduledUpdateTime | Scheduled time to update the widget. The value is in 24-hour format and accurate to minute.<br>**updateDuration** takes precedence over **scheduledUpdateTime**. If both are specified, the value specified by **updateDuration** is used.| String| Yes (initial value: **0:0**)|
| updateDuration | Interval to update the widget. The value is a natural number, in the unit of 30 minutes.<br>If the value is **0**, this field does not take effect.<br>If the value is a positive integer *N*, the interval is calculated by multiplying *N* and 30 minutes.<br>**updateDuration** takes precedence over **scheduledUpdateTime**. If both are specified, the value specified by **updateDuration** is used.| Number| Yes (initial value: **0**)|
| formConfigAbility | Link to a specific page of the application. The value is a URI.| String| Yes (initial value: left empty)|
......@@ -255,7 +257,7 @@ async function storeFormInfo(formId: string, formName: string, tempFlag: boolean
"updateCount": 0
};
try {
const storage = await dataStorage.getStorage(DATA_STORAGE_PATH);
const storage = await dataPreferences.getPreferences(this.context, DATA_STORAGE_PATH);
// put form info
await storage.put(formId, JSON.stringify(formInfo));
console.info(`[EntryFormAbility] storeFormInfo, put form info successfully, formId: ${formId}`);
......@@ -294,8 +296,8 @@ You should override **onRemoveForm** to implement widget data deletion.
const DATA_STORAGE_PATH = "/data/storage/el2/base/haps/form_store";
async function deleteFormInfo(formId: string) {
try {
const storage = await dataStorage.getStorage(DATA_STORAGE_PATH);
// del form info
const storage = await dataPreferences.getPreferences(this.context, DATA_STORAGE_PATH);
// Delete the widget information.
await storage.delete(formId);
console.info(`[EntryFormAbility] deleteFormInfo, del form info successfully, formId: ${formId}`);
await storage.flush();
......@@ -317,7 +319,7 @@ export default class EntryFormAbility extends FormExtension {
}
```
For details about how to implement persistent data storage, see [Persisting Preferences Data](../database/data-persistence-by-preferences.md).
For details about how to implement persistent data storage, see [Application Data Persistence](../database/app-data-persistence-overview.md).
The **Want** object passed in by the widget host to the widget provider contains a flag that specifies whether the requested widget is normal or temporary.
......@@ -449,14 +451,14 @@ The key steps are as follows:
- **action**: **"router"**, which indicates a router event.
- **abilityName**: name of the UIAbility to redirect to (PageAbility component in the FA model and UIAbility component in the stage model). For example, the default UIAbility name of the stage model created by DevEco Studio is EntryAbility.
- **params**: custom parameters passed to the target UIAbility. Set them as required. The value can be obtained from **parameters** in **want** used for starting the target UIAbility. For example, in the lifecycle function **onCreate** of the main ability in the stage model, you can obtain **want** and its **parameters** field.
- **params**: custom parameters passed to the target UIAbility. Set them as required. The value can be obtained from **parameters** in **want** used for starting the target UIAbility. For example, in the lifecycle function **onCreate** of the MainAbility in the stage model, you can obtain **want** and its **parameters** field.
3. Set the message event.
- **action**: **"message"**, which indicates a message event.
- **params**: custom parameters of the message event. Set them as required. The value can be obtained from **message** in the widget lifecycle function **onFormEvent()**.
The following is an example:
The following are examples:
- HML file:
......@@ -545,7 +547,7 @@ The following is an example:
}
```
- Receive the router event and obtain parameters in UIAbility.
- Receive the router event in UIAbility and obtain parameters.
```ts
......
......@@ -80,7 +80,7 @@ To fully understand the preceding example, a knowledge of the following concepts
>
> The name or its class or function name of a custom component must be different from that of any built-in components.
- \@Component: The \@Component decorator can decorate only the data structures declared by the **struct** keyword. After being decorated by \@Component, a struct has the componentization capability. It must implement the **build** function to describe the UI. One struct can be decorated by only one \@Component.
- \@Component: The \@Component decorator can decorate only the structs declared by the **struct** keyword. After being decorated by \@Component, a struct has the componentization capability. It must implement the **build** function to describe the UI. One struct can be decorated by only one \@Component.
> **NOTE**
>
> Since API version 9, this decorator is supported in ArkTS widgets.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册