UIAbility組件與UI的數(shù)據(jù)同步

2024-01-25 12:15 更新

基于HarmonyOS的應(yīng)用模型,可以通過(guò)以下兩種方式來(lái)實(shí)現(xiàn)UIAbility組件與UI之間的數(shù)據(jù)同步。

使用EventHub進(jìn)行數(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ō)明。

  1. 在UIAbility中調(diào)用eventHub.on()方法注冊(cè)一個(gè)自定義事件“event1”,eventHub.on()有如下兩種調(diào)用方式,使用其中一種即可。

    1. import UIAbility from '@ohos.app.ability.UIAbility';
    2. const TAG: string = '[Example].[Entry].[EntryAbility]';
    3. export default class EntryAbility extends UIAbility {
    4. func1(...data) {
    5. // 觸發(fā)事件,完成相應(yīng)的業(yè)務(wù)操作
    6. console.info(TAG, '1. ' + JSON.stringify(data));
    7. }
    8. onCreate(want, launch) {
    9. // 獲取eventHub
    10. let eventhub = this.context.eventHub;
    11. // 執(zhí)行訂閱操作
    12. eventhub.on('event1', this.func1);
    13. eventhub.on('event1', (...data) => {
    14. // 觸發(fā)事件,完成相應(yīng)的業(yè)務(wù)操作
    15. console.info(TAG, '2. ' + JSON.stringify(data));
    16. });
    17. }
    18. }
  2. 在UI界面中通過(guò)eventHub.emit()方法觸發(fā)該事件,在觸發(fā)事件的同時(shí),根據(jù)需要傳入?yún)?shù)信息。

    1. import common from '@ohos.app.ability.common';
    2. @Entry
    3. @Component
    4. struct Index {
    5. private context = getContext(this) as common.UIAbilityContext;
    6. eventHubFunc() {
    7. // 不帶參數(shù)觸發(fā)自定義“event1”事件
    8. this.context.eventHub.emit('event1');
    9. // 帶1個(gè)參數(shù)觸發(fā)自定義“event1”事件
    10. this.context.eventHub.emit('event1', 1);
    11. // 帶2個(gè)參數(shù)觸發(fā)自定義“event1”事件
    12. this.context.eventHub.emit('event1', 2, 'test');
    13. // 開(kāi)發(fā)者可以根據(jù)實(shí)際的業(yè)務(wù)場(chǎng)景設(shè)計(jì)事件傳遞的參數(shù)
    14. }
    15. // 頁(yè)面展示
    16. build() {
    17. // ...
    18. }
    19. }
  3. 在UIAbility的注冊(cè)事件回調(diào)中可以得到對(duì)應(yīng)的觸發(fā)事件結(jié)果,運(yùn)行日志結(jié)果如下所示。

    1. []
    2. [1]
    3. [2,'test']
  4. 在自定義事件“event1”使用完成后,可以根據(jù)需要調(diào)用eventHub.off()方法取消該事件的訂閱。

    1. // context為UIAbility實(shí)例的AbilityContext
    2. this.context.eventHub.off('event1');

使用globalThis進(jìn)行數(shù)據(jù)同步

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的使用:

UIAbility和Page之間使用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ù)信息。

  1. 調(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上。

    1. import UIAbility from '@ohos.app.ability.UIAbility'
    2. export default class EntryAbility extends UIAbility {
    3. onCreate(want, launch) {
    4. globalThis.entryAbilityWant = want;
    5. // ...
    6. }
    7. // ...
    8. }
  2. 在UI界面中即可通過(guò)globalThis獲取到want參數(shù)信息。

    1. let entryAbilityWant;
    2. @Entry
    3. @Component
    4. struct Index {
    5. aboutToAppear() {
    6. entryAbilityWant = globalThis.entryAbilityWant;
    7. }
    8. // 頁(yè)面展示
    9. build() {
    10. // ...
    11. }
    12. }

UIAbility和UIAbility之間使用globalThis

同一個(gè)應(yīng)用中UIAbility和UIAbility之間的數(shù)據(jù)傳遞,可以通過(guò)將數(shù)據(jù)綁定到全局變量globalThis上進(jìn)行同步,如在AbilityA中將數(shù)據(jù)保存在globalThis,然后跳轉(zhuǎn)到AbilityB中取得該數(shù)據(jù):

  1. AbilityA中保存數(shù)據(jù)一個(gè)字符串?dāng)?shù)據(jù)并掛載到globalThis上。

    1. import UIAbility from '@ohos.app.ability.UIAbility'
    2. export default class AbilityA extends UIAbility {
    3. onCreate(want, launch) {
    4. globalThis.entryAbilityStr = 'AbilityA'; // AbilityA存放字符串“AbilityA”到globalThis
    5. // ...
    6. }
    7. }
  2. AbilityB中獲取對(duì)應(yīng)的數(shù)據(jù)。

    1. import UIAbility from '@ohos.app.ability.UIAbility'
    2. export default class AbilityB extends UIAbility {
    3. onCreate(want, launch) {
    4. // AbilityB從globalThis讀取name并輸出
    5. console.info('name from entryAbilityStr: ' + globalThis.entryAbilityStr);
    6. // ...
    7. }
    8. }

globalThis使用的注意事項(xiàng)

圖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ō)明。

  1. 在AbilityA文件中使用globalThis存放了UIAbilityContext

    1. import UIAbility from '@ohos.app.ability.UIAbility'
    2. export default class AbilityA extends UIAbility {
    3. onCreate(want, launch) {
    4. globalThis.context = this.context; // AbilityA存放context到globalThis
    5. // ...
    6. }
    7. }
  2. 在AbilityA的頁(yè)面中獲取該UIAbilityContext并進(jìn)行使用。使用完成后將AbilityA實(shí)例切換至后臺(tái)。

    1. @Entry
    2. @Component
    3. struct Index {
    4. onPageShow() {
    5. let ctx = globalThis.context; // 頁(yè)面中從globalThis中取出context并使用
    6. let permissions = ['com.example.permission']
    7. ctx.requestPermissionsFromUser(permissions,(result) => {
    8. // ...
    9. });
    10. }
    11. // 頁(yè)面展示
    12. build() {
    13. // ...
    14. }
    15. }
  3. 在AbilityB文件中使用globalThis存放了UIAbilityContext,并且命名為相同的名稱(chēng)。

    1. import UIAbility from '@ohos.app.ability.UIAbility'
    2. export default class AbilityB extends UIAbility {
    3. onCreate(want, launch) {
    4. // AbilityB覆蓋了AbilityA在globalThis中存放的context
    5. globalThis.context = this.context;
    6. // ...
    7. }
    8. }
  4. 在AbilityB的頁(yè)面中獲取該UIAbilityContext并進(jìn)行使用。此時(shí)獲取到的globalThis.context已經(jīng)表示為AbilityB中賦值的UIAbilityContext內(nèi)容。

    1. @Entry
    2. @Component
    3. struct Index {
    4. onPageShow() {
    5. let ctx = globalThis.context; // Page中從globalThis中取出context并使用
    6. let permissions = ['com.example.permission']
    7. ctx.requestPermissionsFromUser(permissions,(result) => {
    8. console.info('requestPermissionsFromUser result:' + JSON.stringify(result));
    9. });
    10. }
    11. // 頁(yè)面展示
    12. build() {
    13. // ...
    14. }
    15. }
  5. 在AbilityB實(shí)例切換至后臺(tái),將AbilityA實(shí)例從后臺(tái)切換回到前臺(tái)。此時(shí)AbilityA的onCreate生命周期不會(huì)再次進(jìn)入。

    1. import UIAbility from '@ohos.app.ability.UIAbility'
    2. export default class AbilityA extends UIAbility {
    3. onCreate(want, launch) { // AbilityA從后臺(tái)進(jìn)入前臺(tái),不會(huì)再走這個(gè)生命周期
    4. globalThis.context = this.context;
    5. // ...
    6. }
    7. }
  6. 在AbilityA的頁(yè)面再次回到前臺(tái)時(shí),其獲取到的globalThis.context表示的為AbilityB的UIAbilityContext,而不是AbilityA的UIAbilityContext,在AbilityA的頁(yè)面中使用則會(huì)出錯(cuò)。

    1. @Entry
    2. @Component
    3. struct Index {
    4. onPageShow() {
    5. let ctx = globalThis.context; // 這時(shí)候globalThis中的context是AbilityB的context
    6. let permissions=['com.example.permission'];
    7. ctx.requestPermissionsFromUser(permissions,(result) => { // 使用這個(gè)對(duì)象就會(huì)導(dǎo)致進(jìn)程崩潰
    8. console.info('requestPermissionsFromUser result:' + JSON.stringify(result));
    9. });
    10. }
    11. // 頁(yè)面展示
    12. build() {
    13. // ...
    14. }
    15. }

使用AppStorage/LocalStorage進(jìn)行數(shù)據(jù)同步

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)管理。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)