一、UIAbility组件

1.概述

HarmonyOS中的Stage模型是一种依据UIAbility组件的运用程序架构。UIAbility是HarmonyOS体系中用于构建用户界面的根本组件之一。它负责处理运用程序界面的显现和交互。

在Stage模型中,每个运用程序都有一个或多个Stage。Stage是一个独立的界面容器,能够包含多个UIAbility。每个UIAbility代表了运用程序中的一个界面页面,能够独立展现、交互和办理数据。

UIAbility能够完结不同的功用,比方展现静态信息、接受用户输入、进行数据处理等。它们能够被动态添加或移除,完结动态的界面切换和功用扩展。

经过Stage模型,运用程序能够依据不同的场景和需求,灵敏地安排和办理UIAbility。UIAbility之间能够经过事情和数据进行通讯,完结界面间的交互和数据传递。

{
  "module": {
    // ...
    "abilities": [
      {
        "name": "EntryAbility", // UIAbility组件的称号
        "srcEntrance": "./ets/entryability/EntryAbility.ts", // UIAbility组件的代码途径
        "description": "$string:EntryAbility_desc", // UIAbility组件的描述信息
        "icon": "$media:icon", // UIAbility组件的图标
        "label": "$string:EntryAbility_label", // UIAbility组件的标签
        "startWindowIcon": "$media:icon", // UIAbility组件发动页面图标资源文件的索引
        "startWindowBackground": "$color:start_window_background", // UIAbility组件发动页面布景色彩资源文件的索引
        // ...
      }
    ]
  }
}

鸿蒙HarmonyOS实战-Stage模型(UIAbility组件)

2.生命周期

在HarmonyOS中,Stage模型指的是运用程序的页面层级结构办理办法,经过Stage模型能够完结页面的切换和办理。UIAbility组件是在Stage模型中办理的页面组件,它具有自己的生命周期。

UIAbility的生命周期包含Create、Foreground、Background、Destroy四个状况,如下图所示。

鸿蒙HarmonyOS实战-Stage模型(UIAbility组件)

2.1 生命周期状况阐明

☀️2.1.1 Create状况

在HarmonyOS中,Stage模型是一种用于构建运用程序的UI模型,它由多个UIAbility组件组成。每个UIAbility组件都有自己的生命周期函数,其间包含Create函数。

Create函数是在UIAbility组件被创立时调用的函数。在这个函数中,我们能够进行一些初始化操作,例如创立UI界面资源、绑定事情监听器等。

import UIAbility from '@ohos.app.ability.UIAbility';
import Window from '@ohos.window';
export default class EntryAbility extends UIAbility {
    onCreate(want, launchParam) {
        // 运用初始化
    }
    // ...
}

鸿蒙HarmonyOS实战-Stage模型(UIAbility组件)

☀️2.1.2 WindowStageCreate和WindowStageDestroy状况

WindowStageCreate和WindowStageDestroy是用于创立和毁掉窗口阶段的办法。

WindowStageCreate办法用于创立一个新的窗口阶段,并回来该阶段的句柄。经过该句柄,能够对窗口阶段进行操作,如设置窗口的巨细、位置、布景等。

WindowStageDestroy办法用于毁掉一个窗口阶段,并开释相关的资源。在调用该办法之前,需求先解除与窗口阶段相关的一切绑定,以保证资源能够被正确开释。

鸿蒙HarmonyOS实战-Stage模型(UIAbility组件)

import UIAbility from '@ohos.app.ability.UIAbility';
import Window from '@ohos.window';
export default class EntryAbility extends UIAbility {
    onWindowStageCreate(windowStage: Window.WindowStage) {
        // 设置WindowStage的事情订阅(获焦/失焦、可见/不行见)
        // 设置UI界面加载
        windowStage.loadContent('pages/Index', (err, data) => {
            // ...
        });
    }
    onWindowStageDestroy() {
        // 开释UI界面资源
    }
}

鸿蒙HarmonyOS实战-Stage模型(UIAbility组件)

☀️2.1.3 Foreground和Background状况

运用程序能够处于Foreground(前台)或Background(后台)状况。

Foreground状况是指运用程序当时处于用户正在与之交互的状况,即运用程序在屏幕前面显现并占用用户焦点。在Foreground状况下,运用程序能够接纳用户的输入事情,并在屏幕上显现相关的界面。

Background状况是指运用程序当时不行见,即运用程序在后台运转并不占用用户焦点。在Background状况下,运用程序仍然能够继续履行各种使命,如处理网络恳求、计算等。但是,由于运用程序不行见,因而无法直接与用户进行交互。

HarmonyOS供给了一些机制来办理运用程序的Foreground和Background状况。例如,运用程序能够经过调用API来恳求将自己移至前台或后台,或许能够经过注册生命周期回调来获取自己的状况变化告诉。此外,HarmonyOS还供给了后台使命办理器(BackgroundTaskManager)来办理运用程序在后台履行的使命,以保证后台使命的性能和稳定性。

import UIAbility from '@ohos.app.ability.UIAbility';
export default class EntryAbility extends UIAbility {
    onForeground() {
        // 申请体系需求的资源,或许从头申请在onBackground中开释的资源
    }
    onBackground() {
        // 开释UI界面不行见时无用的资源,或许在此回调中履行较为耗时的操作
        // 例如状况保存等
    }
}

鸿蒙HarmonyOS实战-Stage模型(UIAbility组件)

☀️2.1.4 Destroy状况

Destroy状况是指运用程序现已被彻底毁掉的状况。当运用程序处于Destroy状况时,它的一切资源都被开释,没有任何活动在进行。这意味着运用程序不再存在于体系的活动栈中,而且无法经过回来键或其他办法从头进入。

当运用程序处于Destroy状况时,体系可能会收回运用程序的内存和其他资源,以便为其他运用程序或体系供给更多资源。在Destroy状况下,运用程序的生命周期现已结束,而且它不再对用户可见。

Destroy状况通常在以下情况下产生:

  • 用户手动封闭运用程序;
  • 体系资源缺乏,需求收回运用程序的资源;
  • 运用程序由于反常或错误而被体系强制毁掉。

在HarmonyOS中,运用程序的Destroy状况与其他状况(如Active、Inactive和Paused)相互转换,组成了完好的运用程序生命周期。

import UIAbility from '@ohos.app.ability.UIAbility';
import Window from '@ohos.window';
export default class EntryAbility extends UIAbility {
    onDestroy() {
        // 体系资源的开释、数据的保存等
    }
}

鸿蒙HarmonyOS实战-Stage模型(UIAbility组件)

3.发动形式

3.1 singleton(单实例形式)

单例形式是一种创立只允许存在一个实例的规划形式。在单例形式中,一个类只能创立一个方针,而且供给一个拜访该方针的大局拜访点。

运用单例形式的首要意图是保证在整个运用程序中只有一个实例,这样能够节约体系资源,而且能够方便地控制对该实例的拜访。

单例形式通常选用以下办法完结:

  1. 私有化结构函数:将类的结构函数设置为私有,使得其他类无法直接创立该类的实例。
  2. 供给一个静态办法或特点来获取实例:由于无法直接创立实例,需求供给一个静态办法或特点来获取类的唯一实例。该办法或特点会在第一次调用时创立实例,并在以后的调用中回来同一个实例。
  3. 线程安全:由于多线程环境下,可能会呈现多个线程一起调用获取实例的办法,并测验创立实例的情况。为了保证线程安全,能够运用同步锁或两层检查确定机制来保证只有一个线程能够创立实例。

运用单例形式时需求留意以下几点:

  1. 单例形式会引入大局状况,可能会添加体系的复杂性和耦合度。
  2. 单例形式不适合有多个实例场景的情况。
  3. 单例形式可能会导致单例实例的内存走漏问题,由于该实例在整个运用程序的生命周期中坚持存在。
  4. 单例形式可能会影响代码的可测验性,由于单例实例会在测验中被共享,可能会导致测验成果受到其他测验用例的影响。

在HarmonyOS中每次调用startAbility()办法时,假如运用进程中该类型的UIAbility实例现已存在,则复用体系中的UIAbility实例。体系中只存在唯一一个该UIAbility实例,即在最近使命列表中只存在一个该类型的UIAbility实例。

单例形式装备如下:

{
  "module": {
    // ...
    "abilities": [
      {
        "launchType": "singleton",
        // ...
      }
    ]
  }
}

鸿蒙HarmonyOS实战-Stage模型(UIAbility组件)

3.2 multiton(多实例形式)

Multiton(多实例形式)是规划形式中的一种,它是单例形式的一种变体。在单例形式中,一个类只能有一个实例;而在多实例形式中,一个类能够具有多个实例,每个实例有不同的标识符或键值。每个实例都能够被独立拜访,类似于一个字典结构,能够依据不同的键值获取对应的实例。

Multiton形式通常用于需求创立一组有限且确定数量的类实例的场景。每个实例都有自己的独立状况和行为,但是能够经过共享某些公共资源进行协作。Multiton形式能够供给更大的灵敏性和可扩展性,一起坚持每个实例的独立性。

Multiton形式能够经过运用一个字典或许映射结构来保护每个实例的调集,并经过一个键值来唯一标识每个实例。当需求获取一个实例时,能够依据供给的键值从调集中获取对应的实例。假如调集中不存在对应的实例,则能够创立一个新的实例并添加到调集中。

Multiton形式的长处包含能够灵敏地办理和拜访多个实例,供给更细粒度的控制,一起每个实例都是独立的,能够有自己独立的状况和行为。但是Multiton形式也存在一些缺点,例如需求额定的办理和保护工作,一起可能会导致添加内存消耗。因而,在运用Multiton形式时需求依据详细的需求和场景来进行权衡和挑选。

多实例形式装备如下:

{
  "module": {
    // ...
    "abilities": [
      {
        "launchType": "multiton",
        // ...
      }
    ]
  }
}

鸿蒙HarmonyOS实战-Stage模型(UIAbility组件)

3.3 specified(指定实例形式)

指定实例形式(specified instance pattern)用于束缚一个类只能有固定数意图实例。在这种形式中,类的实例被束缚为预先界说的数量,且这些实例在运转时不能被创立或毁掉。

指定实例形式常用于需求束缚某个类的实例数量的场景。例如,一个数据库连接池的完结能够运用指定实例形式来束缚连接的数量,保证不会创立过多的连接。另一个比如是线程池,能够运用指定实例形式来束缚线程的数量。

在指定实例形式中,通常会保护一个内部的实例列表,来盯梢现已创立的实例。当需求获取一个实例时,会首先检查这个列表,假如列表中现已有满足的实例,则直接回来一个实例给调用者。假如列表中没有满足的实例,则依据需求创立新的实例,并添加到列表中。当实例不再需求时,通常会将其从列表中移除,以便能够继续创立新的实例。

指定实例形式能够有效地控制类的实例数量,避免了资源的浪费和过度创立实例的问题。但是,由于实例数量是固定的,所以可能会呈现竞赛条件和资源瓶颈的问题,需求进行合理的规划和调优。

指定实例形式装备如下:

{
  "module": {
    // ...
    "abilities": [
      {
        "launchType": "specified",
        // ...
      }
    ]
  }
}

鸿蒙HarmonyOS实战-Stage模型(UIAbility组件)

案例阐明:

例如有两个UIAbility:EntryAbility和FuncAbility,FuncAbility装备为specified发动形式,需求从EntryAbility的页面中发动FuncAbility。

1、在FuncAbility中,将module.json5装备文件的”launchType”字段装备为”specified”。

{
  "module": {
    // ...
    "abilities": [
      {
        "launchType": "specified",
        // ...
      }
    ]
  }
}

2、在EntryAbility中,调用startAbility()办法时,在want参数中,添加一个自界说参数来差异UIAbility实例,例如添加一个”instanceKey”自界说参数。

// 在发动指定实例形式的UIAbility时,给每一个UIAbility实例装备一个独立的Key标识
// 例如在文档运用场景中,能够用文档途径作为Key标识
function getInstance() {
    // ...
}
let want = {
    deviceId: '', // deviceId为空表明本设备
    bundleName: 'com.example.myapplication',
    abilityName: 'FuncAbility',
    moduleName: 'module1', // moduleName非必选
    parameters: { // 自界说信息
        instanceKey: getInstance(),
    },
}
// context为调用方UIAbility的AbilityContext
this.context.startAbility(want).then(() => {
    // ...
}).catch((err) => {
    // ...
})

3、获取UIAbility参数

import AbilityStage from '@ohos.app.ability.AbilityStage';
export default class MyAbilityStage extends AbilityStage {
    onAcceptWant(want): string {
        // 在被调用方的AbilityStage中,针对发动形式为specified的UIAbility回来一个UIAbility实例对应的一个Key值
        // 当时示例指的是module1 Module的FuncAbility
        if (want.abilityName === 'FuncAbility') {
            // 回来的字符串Key标识为自界说拼接的字符串内容
            return `ControlModule_EntryAbilityInstance_${want.parameters.instanceKey}`;
        }
        return '';
    }
}

4.根本用法

4.1 指定UIAbility的发动页面

import UIAbility from '@ohos.app.ability.UIAbility';
import Window from '@ohos.window';
export default class EntryAbility extends UIAbility {
    onWindowStageCreate(windowStage: Window.WindowStage) {
        // Main window is created, set main page for this ability
        windowStage.loadContent('pages/Index', (err, data) => {
            // ...
        });
    }
    // ...
}

鸿蒙HarmonyOS实战-Stage模型(UIAbility组件)

4.2 获取UIAbility的上下文信息

经过UIAbilityContext能够获取UIAbility的相关装备信息,包含包代码途径、Bundle称号、Ability称号和运用程序需求的环境状况等特点信息。此外,还能够运用UIAbilityContext供给的办法来操作UIAbility实例,例如startAbility()、connectServiceExtensionAbility()、terminateSelf()等。

import UIAbility from '@ohos.app.ability.UIAbility';
export default class EntryAbility extends UIAbility {
    onCreate(want, launchParam) {
        // 获取UIAbility实例的上下文
        let context = this.context;
        // ...
    }
}

鸿蒙HarmonyOS实战-Stage模型(UIAbility组件)

在页面获取

import common from '@ohos.app.ability.common';
@Entry
@Component
struct Index {
  private context = getContext(this) as common.UIAbilityContext;
  startAbilityTest() {
    let want = {
      // Want参数信息
    };
    this.context.startAbility(want);
  }
  // 页面展现
  build() {
    // ...
  }
}

5.UIAbility组件与UI的数据同步

首要有两种办法:

办法 描述
EventHub 依据发布订阅形式来完结,事情需求先订阅后发布,订阅者收到音讯后进行处理。
globalThis ArkTS引擎实例内部的一个大局方针,在ArkTS引擎实例内部都能拜访。

5.1 运用EventHub进行数据通讯

1、注册事情,运用其间一种即可

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));
        });
    }
}

鸿蒙HarmonyOS实战-Stage模型(UIAbility组件)

2、触发事情

import common from '@ohos.app.ability.common';
@Entry
@Component
struct Index {
  private context = getContext(this) as common.UIAbilityContext;
  eventHubFunc() {
    // 不带参数触发自界说“event1”事情
    this.context.eventHub.emit('event1');
    // 带1个参数触发自界说“event1”事情
    this.context.eventHub.emit('event1', 1);
    // 带2个参数触发自界说“event1”事情
    this.context.eventHub.emit('event1', 2, 'test');
    // 开发者能够依据实践的业务场景规划事情传递的参数
  }
  // 页面展现
  build() {
    // ...
  }
}

3、撤销事情

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

5.2 运用globalThis进行数据同步

在HarmonyOS中,globalThis是一个大局方针,它供给了一个一致的办法来拜访不同环境下的大局方针。在HarmonyOS中,globalThis能够用来拜访当时运转环境中的大局方针,能够是浏览器环境中的window方针,也能够是Node.js环境中的global方针。

运用globalThis能够方便地在不同环境下编写通用的代码,不需求针对不同的环境做特殊的处理。例如,能够运用globalThis来拜访大局的console方针,不管在浏览器环境还是Node.js环境中,都能够运用console.log()来输出日志。

尽管globalThis供给了一种通用的拜访大局方针的办法,但在实践编程中还是主张依据详细的环境来运用相应的大局方针。

鸿蒙HarmonyOS实战-Stage模型(UIAbility组件)

☀️5.2.1 UIAbility和Page之间运用globalThis

1、注册

import UIAbility from '@ohos.app.ability.UIAbility'
export default class EntryAbility extends UIAbility {
    onCreate(want, launch) {
        globalThis.entryAbilityWant = want;
        // ...
    }
    // ...
}

2、获取

let entryAbilityWant;
@Entry
@Component
struct Index {
  aboutToAppear() {
    entryAbilityWant = globalThis.entryAbilityWant;
  }
  // 页面展现
  build() {
    // ...
  }
}

☀️5.2.2 UIAbility和UIAbility之间运用globalThis

1、注册

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

2、获取

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

☀️5.2.3 globalThis运用的留意事项

鸿蒙HarmonyOS实战-Stage模型(UIAbility组件)

案例:

1、在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
        // ...
    }
}

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内容。

@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、在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;
        // ...
    }
}

6、在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() {
    // ...
  }
}

6.UIAbility组件间交互(设备内)

6.1 发动运用内的UIAbility

1、发动方

let wantInfo = {
    deviceId: '', // deviceId为空表明本设备
    bundleName: 'com.example.myapplication',
    abilityName: 'FuncAbility',
    moduleName: 'module1', // moduleName非必选
    parameters: { // 自界说信息
        info: '来自EntryAbility Index页面',
    },
}
// context为调用方UIAbility的AbilityContext
this.context.startAbility(wantInfo).then(() => {
    // ...
}).catch((err) => {
    // ...
})

2、接受方

import UIAbility from '@ohos.app.ability.UIAbility';
import Window from '@ohos.window';
export default class FuncAbility extends UIAbility {
    onCreate(want, launchParam) {
    // 接纳调用方UIAbility传过来的参数
        let funcAbilityWant = want;
        let info = funcAbilityWant?.parameters?.info;
        // ...
    }
}

在FuncAbility业务完结之后,如需求中止当时UIAbility实例,在FuncAbility中经过调用terminateSelf()办法完结。

// context为需求中止的UIAbility实例的AbilityContext
this.context.terminateSelf((err) => {
    // ...
});

6.2 发动运用内的UIAbility并获取回来成果

1、发动方

let wantInfo = {
    deviceId: '', // deviceId为空表明本设备
    bundleName: 'com.example.myapplication',
    abilityName: 'FuncAbility',
    moduleName: 'module1', // moduleName非必选
    parameters: { // 自界说信息
        info: '来自EntryAbility Index页面',
    },
}
// context为调用方UIAbility的AbilityContext
this.context.startAbilityForResult(wantInfo).then((data) => {
    // ...
}).catch((err) => {
    // ...
})

2、接受方

const RESULT_CODE: number = 1001;
let abilityResult = {
    resultCode: RESULT_CODE,
    want: {
        bundleName: 'com.example.myapplication',
        abilityName: 'FuncAbility',
        moduleName: 'module1',
        parameters: {
            info: '来自FuncAbility Index页面',
        },
    },
}
// context为被调用方UIAbility的AbilityContext
this.context.terminateSelfWithResult(abilityResult, (err) => {
    // ...
});

3、获取接受方回调参数

const RESULT_CODE: number = 1001;
// ...
// context为调用方UIAbility的AbilityContext
this.context.startAbilityForResult(want).then((data) => {
    if (data?.resultCode === RESULT_CODE) {
        // 解析被调用方UIAbility回来的信息
        let info = data.want?.parameters?.info;
        // ...
    }
}).catch((err) => {
    // ...
})

6.3 发动其他运用的UIAbility

1、接受方装备信息

{
  "module": {
    "abilities": [
      {
        // ...
        "skills": [
          {
            "entities": [
              // ...
              "entity.system.default"
            ],
            "actions": [
              // ...
              "ohos.want.action.viewData"
            ]
          }
        ]
      }
    ]
  }
}

2、发动方

let wantInfo = {
    deviceId: '', // deviceId为空表明本设备
    // 假如期望隐式仅在特定的绑缚包中进行查询,请撤销下面的注释。
    // bundleName: 'com.example.myapplication',
    action: 'ohos.want.action.viewData',
    // entities能够被省掉。
    entities: ['entity.system.default'],
}
// context为调用方UIAbility的AbilityContext
this.context.startAbility(wantInfo).then(() => {
    // ...
}).catch((err) => {
    // ...
})

鸿蒙HarmonyOS实战-Stage模型(UIAbility组件)

完结后不要忘了,中止

// context为需求中止的UIAbility实例的AbilityContext
this.context.terminateSelf((err) => {
    // ...
});

6.4 发动其他运用的UIAbility并获取回来成果

1、接受方装备信息

{
  "module": {
    "abilities": [
      {
        // ...
        "skills": [
          {
            "entities": [
              // ...
              "entity.system.default"
            ],
            "actions": [
              // ...
              "ohos.want.action.editData"
            ]
          }
        ]
      }
    ]
  }
}

2、发动方

let wantInfo = {
    deviceId: '', // deviceId为空表明本设备
    // uncomment line below if wish to implicitly query only in the specific bundle.
    // bundleName: 'com.example.myapplication',
    action: 'ohos.want.action.editData',
    // entities can be omitted.
    entities: ['entity.system.default'],
}
// context为调用方UIAbility的AbilityContext
this.context.startAbilityForResult(wantInfo).then((data) => {
    // ...
}).catch((err) => {
    // ...
})
const RESULT_CODE: number = 1001;
let abilityResult = {
    resultCode: RESULT_CODE,
    want: {
        bundleName: 'com.example.myapplication',
        abilityName: 'EntryAbility',
        moduleName: 'entry',
        parameters: {
            payResult: 'OKay',
        },
    },
}
// context为被调用方UIAbility的AbilityContext,回来参数
this.context.terminateSelfWithResult(abilityResult, (err) => {
    // ...
});

3、接纳参数

const RESULT_CODE: number = 1001;
let want = {
  // Want参数信息
};
// context为调用方UIAbility的AbilityContext
this.context.startAbilityForResult(want).then((data) => {
    if (data?.resultCode === RESULT_CODE) {
        // 解析被调用方UIAbility回来的信息
        let payResult = data.want?.parameters?.payResult;
        // ...
    }
}).catch((err) => {
    // ...
})

6.5 发动UIAbility的指定页面

☀️6.5.1 调用方UIAbility指定发动页面

let wantInfo = {
    deviceId: '', // deviceId为空表明本设备
    bundleName: 'com.example.myapplication',
    abilityName: 'FuncAbility',
    moduleName: 'module1', // moduleName非必选
    parameters: { // 自界说参数传递页面信息
        router: 'funcA',
    },
}
// context为调用方UIAbility的AbilityContext
this.context.startAbility(wantInfo).then(() => {
    // ...
}).catch((err) => {
    // ...
})

☀️6.5.2 方针UIAbility初次发动

import UIAbility from '@ohos.app.ability.UIAbility'
import Window from '@ohos.window'
export default class FuncAbility extends UIAbility {
    funcAbilityWant;
    onCreate(want, launchParam) {
        // 接纳调用方UIAbility传过来的参数
        this.funcAbilityWant = want;
    }
    onWindowStageCreate(windowStage: Window.WindowStage) {
        // Main window is created, set main page for this ability
        let url = 'pages/Index';
        if (this.funcAbilityWant?.parameters?.router) {
            if (this.funcAbilityWant.parameters.router === 'funA') {
                url = 'pages/Second';
            }
        }
        windowStage.loadContent(url, (err, data) => {
            // ...
        });
    }
}

☀️6.5.3 方针UIAbility非初次发动

鸿蒙HarmonyOS实战-Stage模型(UIAbility组件)

1、接纳方

UIAbility实例之前现已创立完结,此时会进入UIAbility的onNewWant()回调中且不会进入onCreate()和onWindowStageCreate()生命周期回调

import UIAbility from '@ohos.app.ability.UIAbility'
export default class FuncAbility extends UIAbility {
    onNewWant(want, launchParam) {
        // 接纳调用方UIAbility传过来的参数
        globalThis.funcAbilityWant = want;
        // ...
    }
}

2、更新页面UI

FuncAbility对应的Index页面是处于激活状况,不会从头变量声明以及进入aboutToAppear()生命周期回调中。因而能够在Index页面的onPageShow()生命周期回调中完结页面路由跳转的功用。

import router from '@ohos.router';
@Entry
@Component
struct Index {
  onPageShow() {
    let funcAbilityWant = globalThis.funcAbilityWant;
    let url2 = funcAbilityWant?.parameters?.router;
    if (url2 && url2 === 'funcA') {
      router.replaceUrl({
        url: 'pages/Second',
      })
    }
  }
  // 页面展现
  build() {
    // ...
  }
}

6.6 经过Call调用完结UIAbility交互(仅对体系运用开放)

☀️6.6.1 接口阐明

Call调用是UIAbility才能的一种扩展,它允许UIAbility才能被外部调用,并进行通讯。Call调用支撑前台和后台两种发动办法,使得UIAbility能够在前台展现UI或许在后台创立并运转。经过Call调用,调用方和被调用方之间建立了IPC通讯,运用开发者能够利用Call调用完结不同UIAbility之间的数据共享。

Call调用的核心接口是startAbilityByCall办法,与startAbility接口相比,startAbilityByCall具有以下不同之处:

  1. startAbilityByCall支撑前台和后台两种发动办法,而startAbility仅支撑前台发动。
  2. 调用方能够运用startAbilityByCall回来的Caller方针与被调用方进行通讯,而startAbility没有通讯才能。

Call调用的运用场景首要包含:

  1. 需求与被发动的UIAbility进行通讯。
  2. 期望被发动的UIAbility在后台运转。
名词 描述
CallerAbility 进行Call调用的UIAbility(调用方)。
CalleeAbility 被Call调用的UIAbility(被调用方)。
Caller 实践方针,由startAbilityByCall接口回来,CallerAbility可运用Caller与CalleeAbility进行通讯。
Callee 实践方针,被CalleeAbility持有,可与Caller进行通讯。

鸿蒙HarmonyOS实战-Stage模型(UIAbility组件)

☀️6.6.2 开发过程(创立Callee被调用端)

1、装备Ability的发动形式

"abilities":[{
  "name": ".CalleeAbility",
  "srcEntrance": "./ets/CalleeAbility/CalleeAbility.ts",
  "launchType": "singleton",
  "description": "$string:CalleeAbility_desc",
  "icon": "$media:icon",
  "label": "$string:CalleeAbility_label",
  "visible": true
}]

2、导入模块

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

3、界说束缚

export default class MyParcelable {
    num: number = 0
    str: string = ""
    constructor(num, string) {
        this.num = num
        this.str = string
    }
    marshalling(messageSequence) {
        messageSequence.writeInt(this.num)
        messageSequence.writeString(this.str)
        return true
    }
    unmarshalling(messageSequence) {
        this.num = messageSequence.readInt()
        this.str = messageSequence.readString()
        return true
    }
}

4、注册监听和解除监听

const TAG: string = '[CalleeAbility]';
const MSG_SEND_METHOD: string = 'CallSendMsg';
function sendMsgCallback(data) {
    console.info('CalleeSortFunc called');
    // 获取Caller发送的序列化数据
    let receivedData = new MyParcelable(0, '');
    data.readParcelable(receivedData);
    console.info(`receiveData[${receivedData.num}, ${receivedData.str}]`);
    // 作相应处理
    // 回来序列化数据result给Caller
    return new MyParcelable(receivedData.num + 1, `send ${receivedData.str} succeed`);
}
export default class CalleeAbility extends Ability {
    onCreate(want, launchParam) {
        try {
            this.callee.on(MSG_SEND_METHOD, sendMsgCallback);
        } catch (error) {
            console.info(`${MSG_SEND_METHOD} register failed with error ${JSON.stringify(error)}`);
        }
    }
    onDestroy() {
        try {
            this.callee.off(MSG_SEND_METHOD);
        } catch (error) {
            console.error(TAG, `${MSG_SEND_METHOD} unregister failed with error ${JSON.stringify(error)}`);
        }
    }
}

☀️6.6.3 开发过程(拜访Callee被调用端)

1、导入模块

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

2、获取Caller通讯接口

// 注册caller的release监听
private regOnRelease(caller) {
    try {
        caller.on("release", (msg) => {
            console.info(`caller onRelease is called ${msg}`);
        })
        console.info('caller register OnRelease succeed');
    } catch (error) {
        console.info(`caller register OnRelease failed with ${error}`);
    }
}
async onButtonGetCaller() {
    try {
        this.caller = await context.startAbilityByCall({
            bundleName: 'com.samples.CallApplication',
            abilityName: 'CalleeAbility'
        })
        if (this.caller === undefined) {
            console.info('get caller failed')
            return
        }
        console.info('get caller success')
        this.regOnRelease(this.caller)
    } catch (error) {
        console.info(`get caller failed with ${error}`)
    }
}

写在最终

  • 假如你觉得这篇内容对你还蛮有协助,我想邀请你帮我三个小忙:
  • 点赞,转发,有你们的 『点赞和评论』,才是我发明的动力。
  • 重视小编,一起能够等待后续文章ing,不定期共享原创常识。
  • 想要获取最新鸿蒙学习资料,请点击→全套鸿蒙HarmonyOS学习资料

鸿蒙HarmonyOS实战-Stage模型(UIAbility组件)