HarmonyOS/OpenHarmony アプリケーション開発 - ステージモデル UIAbility コンポーネントの使用 (4)

UIAbility コンポーネントと UI 間のデータ同期
HarmonyOS アプリケーション モデルに基づいて、UIAbility コンポーネントと UI 間のデータ同期は次の 2 つの方法で実現できます。
1. EventHub: パブリッシュ/サブスクライブ モデルに基づいて実装されています。イベントは最初にサブスクライブしてからパブリッシュする必要があります。サブスクライバーはメッセージを受信した後に処理します。

2. globalThis: ArkTS エンジン インスタンス内のグローバル オブジェクト。ArkTS エンジン インスタンス内でアクセスできます。

1. データ通信に EventHub を使用する EventHub は
、UIAbility コンポーネント/ExtensionAbility コンポーネント レベルのイベント メカニズムを提供し、UIAbility コンポーネント/ExtensionAbility コンポーネントを中心としたイベントのサブスクライブ、サブスクライブ解除、およびトリガーのためのデータ通信機能を提供します。
EventHub を使用する前に、まず EventHub オブジェクトを取得する必要があります。基本クラス Context は EventHub オブジェクトを提供します。この章では、例として EventHub を使用して UIAbility と UI の間のデータ通信を実装します。

1.UIAbilityのeventHub.on()メソッドを呼び出し、カスタムイベント「event1」を登録します。eventHub.on()には以下の2つの呼び出しメソッドがありますので、いずれかを使用します。

import UIAbility from '@ohos.app.ability.UIAbility';

const TAG: string = '[Example].[Entry].[EntryAbility]';

export default class EntryAbility extends UIAbility {
    func1(...data) {
        // 触发事件,完成相应的业务操作
        console.info(TAG, '1. ' + JSON.stringify(data));
    }

    onCreate(want, launch) {
        // 获取eventHub
        let eventhub = this.context.eventHub;
        // 执行订阅操作
        eventhub.on('event1', this.func1);
        eventhub.on('event1', (...data) => {
            // 触发事件,完成相应的业务操作
            console.info(TAG, '2. ' + JSON.stringify(data));
        });
    }
}

2. UI インターフェイスのeventHub.emit() メソッドを通じてイベントをトリガーし、イベントのトリガー中に必要に応じてパラメーター情報を渡します。

3. 対応するトリガーイベント結果はUIAbilityの登録イベントコールバックで取得でき、操作ログ結果は以下の通りです。

[]

[1]

[2,'test']

4. カスタム イベント「event1」を使用した後、必要に応じて、eventHub.off() メソッドを呼び出してイベントのサブスクリプションをキャンセルできます。

// context为UIAbility实例的AbilityContext
this.context.eventHub.off('event1');

2. データ同期には globalThis を使用します
globalThis は ArkTS エンジン インスタンス内のグローバル オブジェクトであり、エンジン内の UIAbility/ExtensionAbility/Page が利用できるため、globalThis グローバル オブジェクトをデータ同期に使用できます。
図 1 データ同期に globalThis を使用する


上図のように、globalThisの利用シーンと注意点として、
UIAbilityとPageの間でglobalThisを利用する
UIAbilityとUIAbilityの間でglobalThisを利用する
UIAbilityとExtensionAbilityの間でglobalThisを利用する globalThis
利用時の注意点の
3つを紹介します。 UIAbility Page で globalThis を使用します。globalThis
は ArkTS エンジン インスタンスの下のグローバル オブジェクトであり、globalThis を使用してプロパティ/メソッドをバインドし、UIAbility コンポーネントと UI データを同期できます。たとえば、UIAbility コンポーネントで want パラメーターをバインドすると、UIAbility に対応する UI インターフェイスで want パラメーターの情報を使用できます。
1. startAbility() メソッドを呼び出して UIAbility インスタンスを開始すると、開始された UIAbility は作成完了後に onCreate() ライフサイクル コールバックに入り、onCreate() ライフ サイクル コールバックで渡された want パラメーターを受け取ることができます。 、必要なパラメータを設定できます。パラメータは globalThis にバインドされます。

import UIAbility from '@ohos.app.ability.UIAbility'

export default class EntryAbility extends UIAbility {
    onCreate(want, launch) {
        globalThis.entryAbilityWant = want;
        // ...
    }

    // ...
}

2. UI インターフェイスでは、globalThis を通じて必要なパラメータ情報を取得できます。

let entryAbilityWant;

@Entry
@Component
struct Index {
  aboutToAppear() {
    entryAbilityWant = globalThis.entryAbilityWant;
  }

  // 页面展示
  build() {
    // ...
  }
}

3. UIAbility と UIAbility の間で globalThis を使用する
同じアプリケーション内の UIAbility と UIAbility の間のデータ転送は、データをグローバル変数 globalThis にバインドすることによって同期できます。たとえば、AbilityA の globalThis にデータを保存してから、次のデータの取得にジャンプします。アビリティB:
1. アビリティAのデータを文字列データとして保存し、globalThisにマウントします。

import UIAbility from '@ohos.app.ability.UIAbility'

export default class AbilityA extends UIAbility {
    onCreate(want, launch) {
        globalThis.entryAbilityStr = 'AbilityA'; // AbilityA存放字符串“AbilityA”到globalThis
        // ...
    }
}

2.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);
        // ...
    }
}

4. UIAbility と ExtensionAbility の間で globalThis を使用する
同じアプリケーション内の UIAbility と ExtensionAbility の間のデータ転送は、AbilityA でのデータの保存や ServiceExtensionAbility でのデータの取得など、データをグローバル変数 globalThis にバインドすることによって同期することもできます。
1. データ文字列をAbilityAに保存し、globalThisにマウントします。

import UIAbility from '@ohos.app.ability.UIAbility'

export default class AbilityA extends UIAbility {
    onCreate(want, launch) {
        // AbilityA存放字符串“AbilityA”到globalThis
        globalThis.entryAbilityStr = 'AbilityA';
        // ...
    }
}

2. ExtensionAbility でデータを取得します。

import Extension from '@ohos.app.ability.ServiceExtensionAbility'

export default class ServiceExtAbility extends Extension {
    onCreate(want) {
        // ServiceExtAbility从globalThis读取name并输出
        console.info('name from entryAbilityStr: ' + globalThis.entryAbilityStr);
        // ...
    

5. globalThis利用上の注意
図2 globalThis利用上の注意


Stage モデル下のインプロセス UIAbility コンポーネントは ArkTS エンジン インスタンスを共有するため、globalThis を使用する場合は、オブジェクトを同じ名前で保存しないようにする必要があります。たとえば、AbilityA と AbabilityB は、globalThis を使用してデータを共有できます。同じ名前でオブジェクトを保存すると、最初に保存されたオブジェクトは、後で保存されたオブジェクトによって上書きされます。
FA モデルでは、各 UIAbility コンポーネント間のエンジンが分離されているため、この問題は発生しません。
globalThis にバインドされたオブジェクトのライフ サイクルは、ArkTS 仮想マシン インスタンスのライフ サイクルと同じです。アプリケーションのメモリ使用量を削減するために、使用後に null を割り当てることをお勧めします。
ステージモデル上の同名オブジェクトが問題を引き起こすシーンの例を示します。

1. globalThis を使用して、UIAbilityContext を AbabilityA ファイルに保存します。

import UIAbility from '@ohos.app.ability.UIAbility'

export default class AbilityA extends UIAbility {
    onCreate(want, launch) {
        globalThis.context = this.context; // AbilityA存放context到globalThis
        // ...
    }
}

2.AbilityAのページでUIAbilityContextを取得して利用します。使用後は、AbilityA インスタンスをバックグラウンドに切り替えます。

@Entry
@Component
struct Index {
  onPageShow() {
    let ctx = globalThis.context; // 页面中从globalThis中取出context并使用
    let permissions = ['com.example.permission']
    ctx.requestPermissionsFromUser(permissions,(result) => {
       // ...
    });
  }
  // 页面展示
  build() {
    // ...
  }
}

3.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;
        // ...
    }
}

4.AbilityBのページでUIAbilityContextを取得して利用します。このとき取得したglobalThis.contextは、AbilityBに割り当てられたUIAbilityContextのコンテンツとして表現されています。

undefined@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() {
    // ...
  }
}

5. SkillB インスタンスがバックグラウンドに切り替わったら、AbilityA インスタンスをバックグラウンドからフォアグラウンドに戻します。この時点では、AbilityA の onCreate ライフサイクルは再び入りません。

import UIAbility from '@ohos.app.ability.UIAbility'

export default class AbilityA extends UIAbility {
    onCreate(want, launch) { // AbilityA从后台进入前台,不会再走这个生命周期
        globalThis.context = this.context;
        // ...
    }
}

6.再びAbilityAのページが最前面に戻ると、そこで取得したglobalThis.contextはAbilityAのUIAbilityContextではなく、AbilityBの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() {
    // ...
  }
}

おすすめ

転載: blog.csdn.net/weixin_69135651/article/details/131702909
おすすめ