• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Data Synchronization Between UIAbility and UI Page
2
3
4Based on the OpenHarmony application model, you can use any of the following ways to implement data synchronization between UIAbility components and UI pages:
5
6- [Using EventHub for Data Synchronization](#using-eventhub-for-data-synchronization): The **EventHub** object is provided by the base class **Context**. It allows events to be transferred using the publish/subscribe (pub/sub) pattern. Specifically, after subscribing to an event, your application will receive the event and process it accordingly when the event is published.
7- [Using globalThis for Data Synchronization](#using-globalthis-for-data-synchronization): **globalThis** is a global object inside the ArkTS engine instance and can be accessed by the UIAbility components, ExtensionAbility components, and ArkUI pages inside the instance.
8- [Using AppStorage or LocalStorage for Data Synchronization](#using-appstorage-or-localstorage-for-data-synchronization): ArkUI provides two application-level state management solutions: AppStorage and LocalStorage, which implement application- and UIAbility-level data synchronization, respectively.
9
10
11## Using EventHub for Data Synchronization
12
13[EventHub](../reference/apis/js-apis-inner-application-eventHub.md) provides an event mechanism for the UIAbility component so that they can subscribe to, unsubscribe from, and trigger events.
14
15Before using the APIs provided by **EventHub**, you must obtain an **EventHub** object, which is provided by the [base class Context](application-context-stage.md).
16
171. Call [eventHub.on()](../reference/apis/js-apis-inner-application-eventHub.md#eventhubon) in the UIAbility in either of the following ways to register a custom event **event1**.
18
19   ```ts
20   import UIAbility from '@ohos.app.ability.UIAbility';
21
22   const TAG: string = '[Example].[Entry].[EntryAbility]';
23
24   export default class EntryAbility extends UIAbility {
25     func1(...data) {
26       // Trigger the event to complete the service operation.
27       console.info(TAG, '1. ' + JSON.stringify(data));
28     }
29
30     onCreate(want, launch) {
31       // Obtain an eventHub object.
32       let eventhub = this.context.eventHub;
33       // Subscribe to the event.
34       eventhub.on('event1', this.func1);
35       eventhub.on('event1', (...data) => {
36         // Trigger the event to complete the service operation.
37         console.info(TAG, '2. ' + JSON.stringify(data));
38       });
39     }
40   }
41   ```
42
432. Call [eventHub.emit()](../reference/apis/js-apis-inner-application-eventHub.md#eventhubemit) on the UI page to trigger the event, and pass in the parameters as required.
44
45   ```ts
46   import common from '@ohos.app.ability.common';
47
48   @Entry
49   @Component
50   struct Index {
51     private context = getContext(this) as common.UIAbilityContext;
52
53     eventHubFunc() {
54       // Trigger the event without parameters.
55       this.context.eventHub.emit('event1');
56       // Trigger the event with one parameter.
57       this.context.eventHub.emit('event1', 1);
58       // Trigger the event with two parameters.
59       this.context.eventHub.emit('event1', 2, 'test');
60       // You can design the parameters based on your service requirements.
61     }
62
63     // UI page display.
64     build() {
65       ...
66     }
67   }
68   ```
69
703. Obtain the event trigger result from the subscription callback of the UIAbility. The run log result is as follows:
71
72   ```ts
73   []
74
75   [1]
76
77   [2,'test']
78   ```
79
804. When **event1** is not needed, call [eventHub.off()](../reference/apis/js-apis-inner-application-eventHub.md#eventhuboff) to unsubscribe from the event.
81
82   ```ts
83   // context is the AbilityContext of the UIAbility instance.
84   this.context.eventHub.off('event1');
85   ```
86
87
88## Using globalThis for Data Synchronization
89
90**globalThis** is a global object inside the [ArkTS engine instance](thread-model-stage.md) and can be used by UIAbility, ExtensionAbility, and UI page inside the engine. Therefore, you can use **globalThis** for data synchronization.
91
92**Figure 1** Using globalThis for data synchronization
93![globalThis1](figures/globalThis1.png)
94
95
96The following describes how to use **globalThis** in three scenarios. Precautions are provided as well.
97
98- [Using globalThis Between UIAbility and UI Page](#using-globalthis-between-uiability-and-ui-page)
99- [Using globalThis Between UIAbility and UIAbility](#using-globalthis-between-uiability-and-uiability)
100- [Using globalThis Between UIAbility and ExtensionAbility](#using-globalthis-between-uiability-and-extensionability)
101- [Precautions for Using globalThis](#precautions-for-using-globalthis)
102
103### Using globalThis Between UIAbility and UI Page
104
105To implement data synchronization between the UIAbility component and UI page, you can bind attributes or methods to **globalThis**. For example, if you bind the **want** parameter in the UIAbility component, you can use the **want** parameter information on the UI page corresponding to the UIAbility component.
106
1071. When [startAbility()](../reference/apis/js-apis-inner-application-uiAbilityContext.md#uiabilitycontextstartability) is called to start a UIAbility instance, the [onCreate()](../reference/apis/js-apis-app-ability-uiAbility.md#uiabilityoncreate) callback is invoked, and the **want** parameter can be passed in the callback. Bind the **want** parameter to **globalThis**.
108
109   ```ts
110   import UIAbility from '@ohos.app.ability.UIAbility';
111
112   export default class EntryAbility extends UIAbility {
113     onCreate(want, launch) {
114       globalThis.entryAbilityWant = want;
115       ...
116     }
117
118     ...
119   }
120   ```
121
1222. Use **globalThis** on the UI page to obtain the **want** parameter information.
123
124   ```ts
125   let entryAbilityWant;
126
127   @Entry
128   @Component
129   struct Index {
130     aboutToAppear() {
131       entryAbilityWant = globalThis.entryAbilityWant;
132     }
133
134     // UI page display.
135     build() {
136       ...
137     }
138   }
139   ```
140
141
142### Using globalThis Between UIAbility and UIAbility
143
144To implement data synchronization between two UIAbility components in the same application, you can bind data to **globalThis**. For example, you can save data in **globalThis** in UIAbilityA and obtain the data from UIAbilityB.
145
1461. Save data in UIAbilityA and bind it to **globalThis**.
147
148   ```ts
149   import UIAbility from '@ohos.app.ability.UIAbility'
150
151   export default class UIAbilityA extends UIAbility {
152     onCreate(want, launch) {
153       globalThis.entryAbilityStr = 'UIAbilityA'; // UIAbilityA stores the string "UIAbilityA" to globalThis.
154       ...
155     }
156   }
157   ```
158
1592. Obtain the data from UIAbilityB.
160
161   ```ts
162   import UIAbility from '@ohos.app.ability.UIAbility'
163
164   export default class UIAbilityB extends UIAbility {
165     onCreate(want, launch) {
166       // UIAbilityB reads name from globalThis and outputs it.
167       console.info('name from entryAbilityStr: ' + globalThis.entryAbilityStr);
168       ...
169     }
170   }
171   ```
172
173
174### Using globalThis Between UIAbility and ExtensionAbility
175
176To implement data synchronization between the UIAbility and ExtensionAbility components in the same application, you can bind data to **globalThis**. For example, you can save data in **globalThis** in UIAbilityA and obtain the data from ServiceExtensionAbility.
177
1781. Save data in UIAbilityA and bind it to **globalThis**.
179
180   ```ts
181   import UIAbility from '@ohos.app.ability.UIAbility'
182
183   export default class UIAbilityA extends UIAbility {
184     onCreate(want, launch) {
185       // UIAbilityA stores the string "UIAbilityA" to globalThis.
186       globalThis.entryAbilityStr = 'UIAbilityA';
187       ...
188     }
189   }
190   ```
191
1922. Obtain the data from ExtensionAbility.
193
194   ```ts
195   import Extension from '@ohos.app.ability.ServiceExtensionAbility'
196
197   export default class ServiceExtAbility extends Extension {
198     onCreate(want) {
199       / / ServiceExtAbility reads name from globalThis and outputs it.
200       console.info('name from entryAbilityStr: ' + globalThis.entryAbilityStr);
201       ...
202     }
203   }
204   ```
205
206
207### Precautions for Using globalThis
208
209**Figure 2** Precautions for using globalThis
210![globalThis2](figures/globalThis2.png)
211
212- In the stage model, all the UIAbility components in a process share one ArkTS engine instance. When using **globalThis**, do not store objects with the same name. For example, if UIAbilityA and UIAbilityB use **globalThis** to store two objects with the same name, the object stored earlier will be overwritten.
213
214- **globalThis** cannot be used across processes. The UIAbility and ExtensionAbility components of different processes cannot use **globalThis** to share data. For details about the process model and inter-process communication, see [Process Model Overview](./process-model-stage.md#process-model-overview).
215
216- This problem does not occur in the FA model because each UIAbility component uses an independent engine.
217
218- The lifecycle of an object bound to **globalThis** is the same as that of the ArkTS engine instance. To minimize memory usage, you are advised to assign the value **null** to the object when it is not in use.
219
220The following provides an example to describe the object overwritten problem in the stage model.
221
2221. In the UIAbilityA file, use **globalThis** to store [UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md).
223
224   ```ts
225   import UIAbility from '@ohos.app.ability.UIAbility'
226
227   export default class UIAbilityA extends UIAbility {
228     onCreate(want, launch) {
229       globalThis.context = this.context; // UIAbilityA stores the context in globalThis.
230       ...
231     }
232   }
233   ```
234
2352. Obtain and use [UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md) on the UI page of UIAbilityA. When the UIAbilityA instance is not in use, switch it to the background.
236
237   ```ts
238   @Entry
239   @Component
240   struct Index {
241     onPageShow() {
242       let ctx = globalThis.context; // Obtain the context from globalThis and use it.
243     }
244     // UI page display.
245     build() {
246       ...
247     }
248   }
249   ```
250
2513. In the UIAbilityB file, use **globalThis** to store [UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md), which is named the same as that in the UIAbilityA file.
252
253   ```ts
254   import UIAbility from '@ohos.app.ability.UIAbility'
255
256   export default class UIAbilityB extends UIAbility {
257     onCreate(want, launch) {
258       // UIAbilityB overwrites the context stored by UIAbilityA in globalThis.
259       globalThis.context = this.context;
260       ...
261     }
262   }
263   ```
264
2654. Obtain [UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md) from the UI page of UIAbilityB and use it. The obtained **globalThis.context** is the value of [UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md) in UIAbilityB.
266
267   ```ts
268   @Entry
269   @Component
270   struct Index {
271     onPageShow() {
272       let ctx = globalThis.context; // Obtain the context from globalThis and use it.
273     }
274     // UI page display.
275     build() {
276       ...
277     }
278   }
279   ```
280
2815. Switch the UIAbilityB instance to the background and switch the UIAbilityA instance to the foreground. In this case, UIAbilityA will not enter the **onCreate()** lifecycle again.
282
283   ```ts
284   import UIAbility from '@ohos.app.ability.UIAbility'
285
286   export default class UIAbilityA extends UIAbility {
287     onCreate(want, launch) { // UIAbilityA will not enter this lifecycle.
288       globalThis.context = this.context;
289       ...
290     }
291   }
292   ```
293
2946. When the UI page of UIAbilityA is displayed, the obtained **globalThis.context** is the value of [UIAbilityContext](../reference/apis/js-apis-inner-application-uiAbilityContext.md) of UIAbilityB instead of UIAbilityA. An error occurs.
295
296   ```ts
297   @Entry
298   @Component
299   struct Index {
300     onPageShow() {
301       let ctx = globalThis.context; // The context in globalThis is the context of UIAbilityB.
302     }
303     // UI page display.
304     build() {
305       ...
306     }
307   }
308   ```
309
310## Using AppStorage or LocalStorage for Data Synchronization
311
312ArkUI provides AppStorage and LocalStorage to implement application- and UIAbility-level data synchronization, respectively. Both solutions can be used to manage the application state, enhance application performance, and improve user experience. The AppStorage is a global state manager that manages state data shared among multiple UIAbilities. The LocalStorage is a local state manager that manages state data used inside a single UIAbility. They help you control the application state more flexibly and improve the maintainability and scalability of applications. For details, see [State Management of Application-Level Variables](../quick-start/arkts-application-state-management-overview.md).
313