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