W3Cschool
恭喜您成為首批注冊用戶
獲得88經驗值獎勵
基于HarmonyOS的應用模型,可以通過以下兩種方式來實現UIAbility組件與UI之間的數據同步。
EventHub提供了UIAbility組件/ExtensionAbility組件級別的事件機制,以UIAbility組件/ExtensionAbility組件為中心提供了訂閱、取消訂閱和觸發(fā)事件的數據通信能力。接口說明請參見EventHub。
在使用EventHub之前,首先需要獲取EventHub對象。基類Context提供了EventHub對象,本章節(jié)以使用EventHub實現UIAbility與UI之間的數據通信為例進行說明。
在UIAbility中調用eventHub.on()方法注冊一個自定義事件“event1”,eventHub.on()有如下兩種調用方式,使用其中一種即可。
- import UIAbility from '@ohos.app.ability.UIAbility';
- const TAG: string = '[Example].[Entry].[EntryAbility]';
- export default class EntryAbility extends UIAbility {
- func1(...data) {
- // 觸發(fā)事件,完成相應的業(yè)務操作
- console.info(TAG, '1. ' + JSON.stringify(data));
- }
- onCreate(want, launch) {
- // 獲取eventHub
- let eventhub = this.context.eventHub;
- // 執(zhí)行訂閱操作
- eventhub.on('event1', this.func1);
- eventhub.on('event1', (...data) => {
- // 觸發(fā)事件,完成相應的業(yè)務操作
- console.info(TAG, '2. ' + JSON.stringify(data));
- });
- }
- }
在UI界面中通過eventHub.emit()方法觸發(fā)該事件,在觸發(fā)事件的同時,根據需要傳入參數信息。
- import common from '@ohos.app.ability.common';
- @Entry
- @Component
- struct Index {
- private context = getContext(this) as common.UIAbilityContext;
- eventHubFunc() {
- // 不帶參數觸發(fā)自定義“event1”事件
- this.context.eventHub.emit('event1');
- // 帶1個參數觸發(fā)自定義“event1”事件
- this.context.eventHub.emit('event1', 1);
- // 帶2個參數觸發(fā)自定義“event1”事件
- this.context.eventHub.emit('event1', 2, 'test');
- // 開發(fā)者可以根據實際的業(yè)務場景設計事件傳遞的參數
- }
- // 頁面展示
- build() {
- // ...
- }
- }
在UIAbility的注冊事件回調中可以得到對應的觸發(fā)事件結果,運行日志結果如下所示。
- []
- [1]
- [2,'test']
在自定義事件“event1”使用完成后,可以根據需要調用eventHub.off()方法取消該事件的訂閱。
- // context為UIAbility實例的AbilityContext
- this.context.eventHub.off('event1');
globalThis是ArkTS引擎實例內部的一個全局對象,引擎內部的UIAbility/ExtensionAbility/Page都可以使用,因此可以使用globalThis全局對象進行數據同步。
圖1 使用globalThis進行數據同步
如上圖所示,下面來具體介紹globalThis的使用:
globalThis為ArkTS引擎實例下的全局對象,可以通過globalThis綁定屬性/方法來進行UIAbility組件與UI的數據同步。例如在UIAbility組件中綁定want參數,即可在UIAbility對應的UI界面上使用want參數信息。
調用startAbility()方法啟動一個UIAbility實例時,被啟動的UIAbility創(chuàng)建完成后會進入onCreate()生命周期回調,且在onCreate()生命周期回調中能夠接受到傳遞過來的want參數,可以將want參數綁定到globalThis上。
- import UIAbility from '@ohos.app.ability.UIAbility'
- export default class EntryAbility extends UIAbility {
- onCreate(want, launch) {
- globalThis.entryAbilityWant = want;
- // ...
- }
- // ...
- }
在UI界面中即可通過globalThis獲取到want參數信息。
- let entryAbilityWant;
- @Entry
- @Component
- struct Index {
- aboutToAppear() {
- entryAbilityWant = globalThis.entryAbilityWant;
- }
- // 頁面展示
- build() {
- // ...
- }
- }
同一個應用中UIAbility和UIAbility之間的數據傳遞,可以通過將數據綁定到全局變量globalThis上進行同步,如在AbilityA中將數據保存在globalThis,然后跳轉到AbilityB中取得該數據:
AbilityA中保存數據一個字符串數據并掛載到globalThis上。
- import UIAbility from '@ohos.app.ability.UIAbility'
- export default class AbilityA extends UIAbility {
- onCreate(want, launch) {
- globalThis.entryAbilityStr = 'AbilityA'; // AbilityA存放字符串“AbilityA”到globalThis
- // ...
- }
- }
AbilityB中獲取對應的數據。
- import UIAbility from '@ohos.app.ability.UIAbility'
- export default class AbilityB extends UIAbility {
- onCreate(want, launch) {
- // AbilityB從globalThis讀取name并輸出
- console.info('name from entryAbilityStr: ' + globalThis.entryAbilityStr);
- // ...
- }
- }
圖2 globalThis注意事項
Stage模型下進程內的UIAbility組件共享ArkTS引擎實例,使用globalThis時需要避免存放相同名稱的對象。例如AbilityA和AbilityB可以使用globalThis共享數據,在存放相同名稱的對象時,先存放的對象會被后存放的對象覆蓋。
FA模型因為每個UIAbility組件之間引擎隔離,不會存在該問題。
對于綁定在globalThis上的對象,其生命周期與ArkTS虛擬機實例相同,建議在使用完成之后將其賦值為null,以減少對應用內存的占用。
Stage模型上同名對象覆蓋導致問題的場景舉例說明。
在AbilityA文件中使用globalThis存放了UIAbilityContext。
- import UIAbility from '@ohos.app.ability.UIAbility'
- export default class AbilityA extends UIAbility {
- onCreate(want, launch) {
- globalThis.context = this.context; // AbilityA存放context到globalThis
- // ...
- }
- }
在AbilityA的頁面中獲取該UIAbilityContext并進行使用。使用完成后將AbilityA實例切換至后臺。
- @Entry
- @Component
- struct Index {
- onPageShow() {
- let ctx = globalThis.context; // 頁面中從globalThis中取出context并使用
- let permissions = ['com.example.permission']
- ctx.requestPermissionsFromUser(permissions,(result) => {
- // ...
- });
- }
- // 頁面展示
- build() {
- // ...
- }
- }
在AbilityB文件中使用globalThis存放了UIAbilityContext,并且命名為相同的名稱。
- import UIAbility from '@ohos.app.ability.UIAbility'
- export default class AbilityB extends UIAbility {
- onCreate(want, launch) {
- // AbilityB覆蓋了AbilityA在globalThis中存放的context
- globalThis.context = this.context;
- // ...
- }
- }
在AbilityB的頁面中獲取該UIAbilityContext并進行使用。此時獲取到的globalThis.context已經表示為AbilityB中賦值的UIAbilityContext內容。
- @Entry
- @Component
- struct Index {
- onPageShow() {
- let ctx = globalThis.context; // Page中從globalThis中取出context并使用
- let permissions = ['com.example.permission']
- ctx.requestPermissionsFromUser(permissions,(result) => {
- console.info('requestPermissionsFromUser result:' + JSON.stringify(result));
- });
- }
- // 頁面展示
- build() {
- // ...
- }
- }
在AbilityB實例切換至后臺,將AbilityA實例從后臺切換回到前臺。此時AbilityA的onCreate生命周期不會再次進入。
- import UIAbility from '@ohos.app.ability.UIAbility'
- export default class AbilityA extends UIAbility {
- onCreate(want, launch) { // AbilityA從后臺進入前臺,不會再走這個生命周期
- globalThis.context = this.context;
- // ...
- }
- }
在AbilityA的頁面再次回到前臺時,其獲取到的globalThis.context表示的為AbilityB的UIAbilityContext,而不是AbilityA的UIAbilityContext,在AbilityA的頁面中使用則會出錯。
- @Entry
- @Component
- struct Index {
- onPageShow() {
- let ctx = globalThis.context; // 這時候globalThis中的context是AbilityB的context
- let permissions=['com.example.permission'];
- ctx.requestPermissionsFromUser(permissions,(result) => { // 使用這個對象就會導致進程崩潰
- console.info('requestPermissionsFromUser result:' + JSON.stringify(result));
- });
- }
- // 頁面展示
- build() {
- // ...
- }
- }
ArkUI提供了AppStorage和LocalStorage兩種應用級別的狀態(tài)管理方案,可用于實現應用級別和UIAbility級別的數據同步。使用這些方案可以方便地管理應用狀態(tài),提高應用性能和用戶體驗。其中,AppStorage是一個全局的狀態(tài)管理器,適用于多個UIAbility共享同一狀態(tài)數據的情況;而LocalStorage則是一個局部的狀態(tài)管理器,適用于單個UIAbility內部使用的狀態(tài)數據。通過這兩種方案,開發(fā)者可以更加靈活地控制應用狀態(tài),提高應用的可維護性和可擴展性。詳細請參見應用級變量的狀態(tài)管理。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯系方式:
更多建議: