• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Updating Widget Content Through a Proxy
2
3A widget can be updated through a proxy – a system application that has data sharing enabled – when the widget provider is not running.
4
5## Implementation Principles
6
7**Figure 1** Updating widget content through a proxy
8
9![UpdateWidgetByProxyPrinciple](figures/UpdateWidgetByProxyPrinciple.png)
10
11Compared with the [implementation of the ArkTS widget](arkts-form-overview.md#how-to-implement) alone, updating through a proxy involves the data management service and data provider.
12
13- Data management service: provides a mechanism for data sharing among multiple applications.
14- Data provider: must be a system application that has data sharing enabled. The shared data is identified through the defined `key + subscriberId` combination.
15
16> **NOTE**
17>
18> This feature can be used when the system provides applications as data providers and publicly available shared data identifiers.
19
20Processing flow of the widget provider (indicated by the blue arrows in the figure):
21
221. The widget provider sets the `dataProxyEnabled` field to `true` in the `form_config.json` file to enable the update-through-proxy feature.
23> **NOTE**
24>
25> After the update-through-proxy feature is enabled, the settings for [interval-based update](arkts-ui-widget-passive-refresh.md#interval-based-update) becomes invalid.
26
272. In the [onAddForm](../reference/apis-form-kit/js-apis-app-form-formExtensionAbility.md#formextensionabilityonaddform) callback, the widget provider returns the `key + subscriberId` combination defined by the data provider to the Widget Manager.
28
293. The Widget Manager parses the subscription information of the widget provider and registers a subscription instance with the data management service.
30
31Processing flow of the widget update proxy (indicated by the red arrows in the figure):
32
331. The data provider uses the `key + subscriberId` combination as the data ID to store data to the database.
342. The data management service detects the change in the database and publishes the new data to all currently registered subscription instances.
353. The Widget Manager parses data from the subscription instance and sends the data to the widget rendering service.
364. The widget rendering service runs the widget page code **widgets.abc**, which implements rendering based on the new data and sends the rendered data to the <!--Del-->[<!--DelEnd-->FormComponent<!--Del-->](../reference/apis-arkui/arkui-ts/ts-basic-components-formcomponent-sys.md)<!--DelEnd--> corresponding to the widget host.
37
38There are two types of shared data provided by the data provider:
39
40- Ephemeral data: data that exists only for a specific period of time and can be subscribed to by system and non-system applications alike.
41
42- Persistent data: data that can be subscribed to only by system applications.
43
44The update-through-proxy configuration varies by the type of shared data.
45<!--Del-->
46## Data Provider Development
47
48For details, see [Data Management](../database/share-data-by-silent-access.md).
49<!--DelEnd-->
50## Widget Provider Development (Ephemeral Data)
51
52- Set the `dataProxyEnabled` field to `true` in the **form_config.json** file to enable the update-through-proxy feature. When the subscribed ephemeral data is updated, the system automatically updates the widget data.
53  ```json
54  {
55    "forms": [
56      {
57        "name": "WidgetProcessData",
58        "description": "$string:ProcessDataEntryAbility_desc",
59        "src": "./ets/widgetprocessdata/pages/WidgetProcessDataCard.ets",
60        "uiSyntax": "arkts",
61        "window": {
62          "designWidth": 720,
63          "autoDesignWidth": true
64        },
65        "colorMode": "auto",
66        "isDefault": true,
67        "updateEnabled": true,
68        "scheduledUpdateTime": "10:30",
69        "defaultDimension": "2*2",
70        "supportDimensions": [
71          "2*2"
72        ],
73        "dataProxyEnabled": true
74      }
75    ]
76  }
77  ```
78
79- Configure the subscription information [proxyData](../reference/apis-form-kit/js-apis-app-form-formBindingData.md#proxydata10) in the [onAddForm](../reference/apis-form-kit/js-apis-app-form-formExtensionAbility.md#formextensionabilityonaddform) callback and return the information to the Widget Manager through [formBinding](../reference/apis-form-kit/js-apis-app-form-formBindingData.md#formbindingdata). In this example, **key** is set to **datashareproxy://com.samples.widgetupdatebyproxy/weather** and **subscriberId** is set to **11**.
80  > **NOTE**
81  >
82  > 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.
83  ```ts
84  import { formBindingData, FormExtensionAbility } from '@kit.FormKit';
85  import { Want } from '@kit.AbilityKit';
86  import { hilog } from '@kit.PerformanceAnalysisKit';
87
88  const TAG: string = 'ProcessDataFormAbility';
89  const DOMAIN_NUMBER: number = 0xFF00;
90
91  export default class ProcessDataFormAbility extends FormExtensionAbility {
92    onAddForm(want: Want): formBindingData.FormBindingData {
93      let formData: Record<string, Object> = {};
94      let proxies: formBindingData.ProxyData[] = [
95        {
96          key: 'datashareproxy://com.samples.widgetupdatebyproxy/weather',
97          subscriberId: '11'
98        }
99      ];
100      let formBinding = formBindingData.createFormBindingData(formData);
101      formBinding.proxies = proxies;
102      hilog.info(DOMAIN_NUMBER, TAG, 'onAddForm');
103      return formBinding;
104    }
105  }
106  ```
107
108- In the [widget page code file](arkts-ui-widget-creation.md), use the variable in LocalStorage to obtain the subscribed data. The variable in LocalStorage is bound to a string and updates the subscribed data in the key:value pair format. The key must be the same as that subscribed to by the widget provider. In this example, the subscribed data is obtained through **'city'** and displayed in the **\<Text>** component.
109  ```ts
110  let storageProcess = new LocalStorage();
111
112  @Entry(storageProcess)
113  @Component
114  struct WidgetProcessDataCard {
115    @LocalStorageProp('datashareproxy://com.samples.widgetupdatebyproxy/weather') city: ResourceStr = $r('app.string.loading');
116
117    build() {
118      Column() {
119        Column() {
120          Text(this.city)
121            .fontColor('#FFFFFF')
122            .opacity(0.9)
123            .fontSize(14)
124            .margin({ top: '8%', left: '10%' })
125        }.width('100%')
126        .alignItems(HorizontalAlign.Start)
127      }.width('100%').height('100%')
128      .backgroundImage($r('app.media.CardEvent'))
129      .backgroundImageSize(ImageSize.Cover)
130    }
131  }
132  ```
133
134## Widget Provider Development (Persistent Data)
135- Set the `dataProxyEnabled` field to `true` in the **form_config.json** file to enable the update-through-proxy feature.
136  ```json
137  {
138    "forms": [
139      {
140        "name": "WidgetPersistentData",
141        "description": "This is a service widget update by proxy using persistent data.",
142        "src": "./ets/widgetpersistentdata/pages/WidgetPersistentDataCard.ets",
143        "uiSyntax": "arkts",
144        "window": {
145          "designWidth": 720,
146          "autoDesignWidth": true
147        },
148        "colorMode": "auto",
149        "isDefault": true,
150        "updateEnabled": true,
151        "scheduledUpdateTime": "10:30",
152        "updateDuration": 1,
153        "defaultDimension": "2*2",
154        "supportDimensions": [
155          "2*2"
156        ],
157        "dataProxyEnabled": true
158      }
159  ]
160  }
161  ```
162
163- Add a subscription template <!--Del-->[<!--DelEnd-->addTemplate<!--Del-->](../reference/apis-arkdata/js-apis-data-dataShare-sys.md#addtemplate10)<!--DelEnd--> to the [onAddForm](../reference/apis-form-kit/js-apis-app-form-formExtensionAbility.md#formextensionabilityonaddform) callback and use the template predicates to notify the database of the subscribed data conditions. Then, configure the subscription information [proxyData](../reference/apis-form-kit/js-apis-app-form-formBindingData.md#proxydata10) and return it to the Widget Manager through [FormBindingData](../reference/apis-form-kit/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. When the subscribed persistent data is updated, the system automatically updates the widget data.
164
165  > **NOTE**
166  >
167  > - The value of **key** is a URI, which depends on the definition of the data release party.
168  > - The value of **subscriberId** can be customized. Ensure that the value of **subscriberId** in **addTemplate** is the same as that of **proxies.subscriberId**.
169  ```ts
170  import { formBindingData, FormExtensionAbility } from '@kit.FormKit';
171  import { Want } from '@kit.AbilityKit';
172  import { dataShare } from '@kit.ArkData';
173
174  export default class PersistentDataFormAbility extends FormExtensionAbility {
175    onAddForm(want: Want): formBindingData.FormBindingData {
176      let subscriberId = '111';
177      let template: dataShare.Template = {
178        predicates: {
179          'list': `select type from TBL00 where cityId = ${subscriberId}`
180        },
181        scheduler: ''
182      };
183      dataShare.createDataShareHelper(this.context, 'datashareproxy://com.samples.widgetupdatebyproxy', {
184        isProxy: true
185      }).then((data) => {
186        let dataShareHelper = data;
187        dataShareHelper.addTemplate('datashareproxy://com.samples.widgetupdatebyproxy/test', subscriberId, template);
188      });
189      let formData: Record<string, Object> = {};
190      let proxies: formBindingData.ProxyData[] = [
191        {
192          key: 'datashareproxy://com.samples.widgetupdatebyproxy/test',
193          subscriberId: subscriberId
194        }
195      ];
196
197      let formBinding: formBindingData.FormBindingData = {
198        data: JSON.stringify(formData),
199        proxies: proxies
200      };
201      return formBinding;
202    }
203  }
204  ```
205
206- In the [widget page code file](arkts-ui-widget-creation.md), use the variable in LocalStorage to obtain the subscribed data. The variable in LocalStorage is bound to a string and updates the subscribed data in the key:value pair format. The key must be the same as that subscribed to by the widget provider. In the example, the subscribed data is obtained through **'list'**, and the value of the first element is displayed on the **\<Text>** component.
207  ```ts
208  let storagePersis = new LocalStorage();
209
210  @Entry(storagePersis)
211  @Component
212  struct WidgetPersistentDataCard {
213    readonly FULL_WIDTH_PERCENT: string = '100%';
214    readonly FULL_HEIGHT_PERCENT: string = '100%';
215    @LocalStorageProp('list') list: Record<string, string>[] = [{ 'type': 'a' }];
216
217    build() {
218      Column() {
219        Column() {
220          Text((this.list[0]['type']))
221            .fontColor('#FFFFFF')
222            .opacity(0.9)
223            .fontSize(14)
224            .margin({ top: '8%', left: '10%' })
225        }.width('100%')
226        .alignItems(HorizontalAlign.Start)
227      }.width(this.FULL_WIDTH_PERCENT).height(this.FULL_HEIGHT_PERCENT)
228      .backgroundImage($r('app.media.CardEvent'))
229      .backgroundImageSize(ImageSize.Cover)
230    }
231  }
232  ```
233
234