「鸿蒙学习笔记」Stage模型--UIAbility

概述

UIAbility组件是一种蕴含UI界面的利用组件,次要用于和用户交互。

UIAbility组件是系统调度的根本单元,为利用提供绘制界面的窗口;一个UIAbility组件中能够通过多个页面来实现一个功能模块。每一个UIAbility组件实例,都对应于一个最近工作列表中的工作。

配置

为使利用可能失常应用UIAbility,须要在 module.json5 配置文件的 abilities标签 中申明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组件启动页面背景色彩资源文件的索引        // ...      }    ]  }}

生命周期

启动模式

针对不同的业务场景,零碎提供了三种启动模式:

  • singleton(单实例模式)
  • standard(规范实例模式)
  • specified(指定实例模式)

singleton(单实例模式)

singleton启动模式为单实例模式,也是默认状况下的启动模式。

每次调用startAbility()办法时,如果利用过程中该类型的UIAbility实例曾经存在,则复用零碎中的UIAbility实例。零碎中只存在惟一一个该UIAbility实例,即在最近工作列表中只存在一个该类型的UIAbility实例。

利用的UIAbility实例已创立,该UIAbility配置为单实例模式,再次调用startAbility()办法启动该UIAbility实例,此时只会进入该UIAbility的onNewWant()回调,不会进入其onCreate()和onWindowStageCreate()生命周期回调。

在module.json5配置文件中的"launchType"字段配置为"singleton"即可。

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

standard(规范实例模式)

standard启动模式为规范实例模式,每次调用startAbility()办法时,都会在利用过程中创立一个新的该类型UIAbility实例。即在最近工作列表中能够看到有多个该类型的UIAbility实例。这种状况下能够将UIAbility配置为standard(规范实例模式)。

在module.json5配置文件中的"launchType"字段配置为"standard"即可。

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

specified(指定实例模式)

specified启动模式为指定实例模式,针对一些非凡场景应用(例如文档利用中每次新建文档心愿都能新建一个文档实例,反复关上一个已保留的文档心愿关上的都是同一个文档实例)。

在UIAbility实例创立之前,容许开发者为该实例创立一个惟一的字符串Key,创立的UIAbility实例绑定Key之后,后续每次调用startAbility()办法时,都会询问利用应用哪个Key对应的UIAbility实例来响应startAbility()申请。运行时由UIAbility外部业务决定是否创立多实例,如果匹配有该UIAbility实例的Key,则间接拉起与之绑定的UIAbility实例,否则创立一个新的UIAbility实例。

利用的UIAbility实例已创立,该UIAbility配置为指定实例模式,再次调用startAbility()办法启动该UIAbility实例,且AbilityStage的onAcceptWant()回调匹配到一个已创立的UIAbility实例。此时,再次启动该UIAbility时,只会进入该UIAbility的onNewWant()回调,不会进入其onCreate()和onWindowStageCreate()生命周期回调。

例如有两个UIAbility:EntryAbility和FuncAbility,FuncAbility配置为specified启动模式,须要从EntryAbility的页面中启动FuncAbility。

  1. 在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的AbilityContextthis.context.startAbility(want).then(() => { // ...}).catch((err) => { // ...})
  3. 因为FuncAbility的启动模式配置为了指定实例启动模式,在FuncAbility启动之前,会先进入其对应的AbilityStage的onAcceptWant()生命周期回调中,解析传入的want参数,获取"instanceKey"自定义参数。依据业务须要通过AbilityStage的onAcceptWant()生命周期回调返回一个字符串Key标识。如果返回的Key对应一个已启动的UIAbility,则会将之前的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 ''; }}

例如在文档利用中,能够对不同的文档实例内容绑定不同的Key值。当每次新建文档的时候,能够传入不同的新Key值(如能够将文件的门路作为一个Key标识),此时AbilityStage中启动UIAbility时都会创立一个新的UIAbility实例;当新建的文档保留之后,回到桌面,或者新关上一个已保留的文档,回到桌面,此时再次关上该已保留的文档,此时AbilityStage中再次启动该UIAbility时,关上的依然是之前原来已保留的文档界面。

根本用法

指定UIAbility的启动页面

利用中的UIAbility在启动过程中,须要指定启动页面,否则利用启动后会因为没有默认加载页面而导致白屏。能够在UIAbility的onWindowStageCreate()生命周期回调中,通过WindowStage对象的loadContent()办法设置启动页面。

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

获取UIAbility的上下文信息

UIAbility类领有本身的上下文信息,该信息为UIAbilityContext类的实例,UIAbilityContext类领有abilityInfo、currentHapModuleInfo等属性。通过UIAbilityContext能够获取UIAbility的相干配置信息,如包代码门路、Bundle名称、Ability名称和应用程序须要的环境状态等属性信息,以及能够获取操作UIAbility实例的办法(如startAbility()、connectServiceExtensionAbility()、terminateSelf()等)。

  • 在UIAbility中能够通过this.context获取UIAbility实例的上下文信息。

    import UIAbility from '@ohos.app.ability.UIAbility';export default class EntryAbility extends UIAbility {  onCreate(want, launchParam) {      // 获取UIAbility实例的上下文      let context = this.context;      // ...  }}
  • 在页面中获取UIAbility实例的上下文信息,包含导入依赖资源context模块和在组件中定义一个context变量两个局部。

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

UI数据同步

基于HarmonyOS的利用模型,能够通过以下两种形式来实现UIAbility组件与UI之间的数据同步。

  • EventHub:基于公布订阅模式来实现,事件须要先订阅后公布,订阅者收到音讯后进行解决。
  • globalThis:ArkTS引擎实例外部的一个全局对象,在ArkTS引擎实例外部都能拜访。

应用EventHub进行数据通信

EventHub提供了UIAbility组件/ExtensionAbility组件级别的事件机制,以UIAbility组件/ExtensionAbility组件为核心提供了订阅、勾销订阅和触发事件的数据通信能力。接口阐明请参见EventHub。

在应用EventHub之前,首先须要获取EventHub对象。基类Context提供了EventHub对象,本章节以应用EventHub实现UIAbility与UI之间的数据通信为例进行阐明。

  1. 在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) {        // 触发事件,实现相应的业务操作        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));        });    }}
  1. 在UI界面中通过eventHub.emit()办法触发该事件,在触发事件的同时,依据须要传入参数信息。

    import common from '@ohos.app.ability.common';@Entry@Componentstruct 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() { // ...  }}
  2. 在UIAbility的注册事件回调中能够失去对应的触发事件后果,运行日志后果如下所示。

    [][1][2,'test']
  3. 在自定义事件“event1”应用实现后,能够依据须要调用eventHub.off()办法勾销该事件的订阅。

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

应用globalThis进行数据同步

globalThis是ArkTS引擎实例外部的一个全局对象,引擎外部的UIAbility/ExtensionAbility/Page都能够应用,因而能够应用globalThis全局对象进行数据同步。

从如下三个场景和一个留神点来介绍globalThis的应用:

  • UIAbility和Page之间应用globalThis
  • UIAbility和UIAbility之间应用globalThis
  • UIAbility和ExtensionAbility之间应用globalThis
  • globalThis应用的注意事项
UIAbility和Page之间应用globalThis

globalThis为ArkTS引擎实例下的全局对象,能够通过globalThis绑定属性/办法来进行UIAbility组件与UI的数据同步。例如在UIAbility组件中绑定want参数,即可在UIAbility对应的UI界面上应用want参数信息。

  1. 调用startAbility()办法启动一个UIAbility实例时,被启动的UIAbility创立实现后会进入onCreate()生命周期回调,且在onCreate()生命周期回调中可能承受到传递过去的want参数,能够将want参数绑定到globalThis上。

    import UIAbility from '@ohos.app.ability.UIAbility'export default class EntryAbility extends UIAbility { onCreate(want, launch) {     globalThis.entryAbilityWant = want;     // ... } // ...}
  2. 在UI界面中即可通过globalThis获取到want参数信息。

    let entryAbilityWant;@Entry@Componentstruct Index {  aboutToAppear() { entryAbilityWant = globalThis.entryAbilityWant;  }  // 页面展现  build() { // ...  }}
UIAbility和UIAbility之间应用globalThis

同一个利用中UIAbility和UIAbility之间的数据传递,能够通过将数据绑定到全局变量globalThis上进行同步,如在AbilityA中将数据保留在globalThis,而后跳转到AbilityB中获得该数据:

  1. AbilityA中保留数据一个字符串数据并挂载到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);     // ... }}
UIAbility和ExtensionAbility之间应用globalThis

同一个利用中UIAbility和ExtensionAbility之间的数据传递,也能够通过将数据绑定到全局变量globalThis上进行同步,如在AbilityA中保留数据,在ServiceExtensionAbility中获取数据。

  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);     // ... }}
globalThis应用的注意事项

  • Stage模型下过程内的UIAbility组件共享ArkTS引擎实例,应用globalThis时须要防止寄存雷同名称的对象。例如AbilityA和AbilityB能够应用globalThis共享数据,在寄存雷同名称的对象时,先寄存的对象会被后寄存的对象笼罩。
  • 对于绑定在globalThis上的对象,其生命周期与ArkTS虚拟机实例雷同,倡议在应用实现之后将其赋值为null,以缩小对利用内存的占用。

组件间交互(设施内)

UIAbility是系统调度的最小单元。在设施内的功能模块之间跳转时,会波及到启动特定的UIAbility,该UIAbility能够是利用内的其余UIAbility,也能够是其余利用的UIAbility(例如启动三方领取UIAbility)。

  • 启动利用内的UIAbility
  • 启动利用内的UIAbility并获取返回后果
  • 启动其余利用的UIAbility
  • 启动其余利用的UIAbility并获取返回后果
  • 启动UIAbility的指定页面
  • 通过Call调用实现UIAbility交互(仅对系统利用凋谢)

启动利用内的UIAbility

当一个利用内蕴含多个UIAbility时,存在利用内启动UIAbility的场景。例如在领取利用中从入口UIAbility启动收付款UIAbility。

假如利用中有两个UIAbility:EntryAbility和FuncAbility(能够在利用的一个Module中,也能够在的不同Module中),须要从EntryAbility的页面中启动FuncAbility。

  1. 在EntryAbility中,通过调用startAbility()办法启动UIAbility,want为UIAbility实例启动的入口参数,其中bundleName为待启动利用的Bundle名称,abilityName为待启动的UIAbility名称,moduleName在待启动的UIAbility属于不同的Module时增加,parameters为自定义信息参数。

    let wantInfo = { deviceId: '', // deviceId为空示意本设施 bundleName: 'com.example.myapplication', abilityName: 'FuncAbility', moduleName: 'module1', // moduleName非必选 parameters: { // 自定义信息     info: '来自EntryAbility Index页面', },}// context为调用方UIAbility的AbilityContextthis.context.startAbility(wantInfo).then(() => { // ...}).catch((err) => { // ...})
  2. 在FuncAbility的生命周期回调文件中接管EntryAbility传递过去的参数。

    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;     // ... }}
  3. 在FuncAbility业务实现之后,如须要进行以后UIAbility实例,在FuncAbility中通过调用terminateSelf()办法实现。

    // context为须要进行的UIAbility实例的AbilityContextthis.context.terminateSelf((err) => { // ...});

启动利用内的UIAbility并获取返回后果

在一个EntryAbility启动另外一个FuncAbility时,心愿在被启动的FuncAbility实现相干业务后,能将后果返回给调用方。例如在利用中将入口性能和帐号登录性能别离设计为两个独立的UIAbility,在帐号登录UIAbility中实现登录操作后,须要将登录的后果返回给入口UIAbility。

  1. 在EntryAbility中,调用startAbilityForResult()接口启动FuncAbility,异步回调中的data用于接管FuncAbility进行本身后返回给EntryAbility的信息。

    let wantInfo = { deviceId: '', // deviceId为空示意本设施 bundleName: 'com.example.myapplication', abilityName: 'FuncAbility', moduleName: 'module1', // moduleName非必选 parameters: { // 自定义信息     info: '来自EntryAbility Index页面', },}// context为调用方UIAbility的AbilityContextthis.context.startAbilityForResult(wantInfo).then((data) => { // ...}).catch((err) => { // ...})
  2. 在FuncAbility进行本身时,须要调用terminateSelfWithResult()办法,入参abilityResult为FuncAbility须要返回给EntryAbility的信息。

    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的AbilityContextthis.context.terminateSelfWithResult(abilityResult, (err) => { // ...});
  3. FuncAbility进行本身后,EntryAbility通过startAbilityForResult()办法回调接管被FuncAbility返回的信息,RESULT_CODE须要与后面的数值保持一致。

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

启动其余利用的UIAbility

启动其余利用的UIAbility,通常用户只须要实现一个通用的操作(例如须要抉择一个文档利用来查看某个文档的内容信息),举荐应用隐式Want启动。零碎会依据调用方的want参数来辨认和启动匹配到的利用UIAbility。

启动UIAbility有显式Want启动和隐式Want启动两种形式。

  • 显式Want启动:启动一个确定利用的UIAbility,在want参数中须要设置该利用bundleName和abilityName,当须要拉起某个明确的UIAbility时,通常应用显式Want启动形式。
  • 隐式Want启动:依据匹配条件由用户抉择启动哪一个UIAbility,即不明确指出要启动哪一个UIAbility(abilityName参数未设置),在调用startAbility()办法时,其入参want中指定了一系列的entities字段(示意指标UIAbility额定的类别信息,如浏览器、视频播放器)和actions字段(示意要执行的通用操作,如查看、分享、利用详情等)等参数信息,而后由零碎去剖析want,并帮忙找到适合的UIAbility来启动。当须要拉起其余利用的UIAbility时,开发者通常不晓得用户设施中利用的装置状况,也无奈确定指标利用的bundleName和abilityName,通常应用隐式Want启动形式。

隐式Want启动其余利用的UIAbility:

  1. 将多个待匹配的文档利用装置到设施,在其对应UIAbility的module.json5配置文件中,配置skills的entities字段和actions字段。

    {  "module": { "abilities": [   {     // ...     "skills": [       {         "entities": [           // ...           "entity.system.default"         ],         "actions": [           // ...           "ohos.want.action.viewData"         ]       }     ]   } ]  }}
  2. 在调用方want参数中的entities和action须要被蕴含在待匹配UIAbility的skills配置的entities和actions中。零碎匹配到合乎entities和actions参数条件的UIAbility后,会弹出抉择框展现匹配到的UIAbility实例列表供用户抉择应用。

    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.viewData', // entities can be omitted. entities: ['entity.system.default'],}// context为调用方UIAbility的AbilityContextthis.context.startAbility(wantInfo).then(() => { // ...}).catch((err) => { // ...})

  3. 在文档利用应用实现之后,如须要进行以后UIAbility实例,通过调用terminateSelf()办法实现。

    // context为须要进行的UIAbility实例的AbilityContextthis.context.terminateSelf((err) => { // ...});

启动其余利用的UIAbility并获取返回后果

当应用隐式Want启动其余利用的UIAbility并心愿获取返回后果时,调用方须要应用startAbilityForResult()办法启动指标UIAbility。例如主利用中须要启动三方领取并获取领取后果。

  1. 在领取利用对应UIAbility的module.json5配置文件中,配置skills的entities字段和actions字段。

    {  "module": { "abilities": [   {     // ...     "skills": [       {         "entities": [           // ...           "entity.system.default"         ],         "actions": [           // ...           "ohos.want.action.editData"         ]       }     ]   } ]  }}
  2. 调用方应用startAbilityForResult()办法启动领取利用的UIAbility,在调用方want参数中的entities和action须要被蕴含在待匹配UIAbility的skills配置的entities和actions中。异步回调中的data用于后续接管领取UIAbility进行本身后返回给调用方的信息。零碎匹配到合乎entities和actions参数条件的UIAbility后,会弹出抉择框展现匹配到的UIAbility实例列表供用户抉择应用。

    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的AbilityContextthis.context.startAbilityForResult(wantInfo).then((data) => { // ...}).catch((err) => { // ...})
  3. 在领取UIAbility实现领取之后,须要调用terminateSelfWithResult()办法实现进行本身,并将abilityResult参数信息返回给调用方。

    const RESULT_CODE: number = 1001;let abilityResult = { resultCode: RESULT_CODE, want: {     bundleName: 'com.example.myapplication',     abilityName: 'EntryAbility',     moduleName: 'entry',     parameters: {         payResult: 'OKay',     }, },}// context为被调用方UIAbility的AbilityContextthis.context.terminateSelfWithResult(abilityResult, (err) => { // ...});
  4. 在调用方startAbilityForResult()办法回调中接管领取利用返回的信息,RESULT_CODE须要与后面terminateSelfWithResult()返回的数值保持一致。

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

启动UIAbility的指定页面

一个UIAbility能够对应多个页面,在不同的场景下启动该UIAbility时须要展现不同的页面,例如从一个UIAbility的页面中跳转到另外一个UIAbility时,心愿启动指标UIAbility的指定页面。

调用方UIAbility指定启动页面

调用方UIAbility启动另外一个UIAbility时,通常须要跳转到指定的页面。例如FuncAbility蕴含两个页面(Index对应首页,Second对应性能A页面),此时须要在传入的want参数中配置指定的页面门路信息,能够通过want中的parameters参数减少一个自定义参数传递页面跳转信息。

let wantInfo = {    deviceId: '', // deviceId为空示意本设施    bundleName: 'com.example.myapplication',    abilityName: 'FuncAbility',    moduleName: 'module1', // moduleName非必选    parameters: { // 自定义参数传递页面信息        router: 'funcA',    },}// context为调用方UIAbility的AbilityContextthis.context.startAbility(wantInfo).then(() => {    // ...}).catch((err) => {    // ...})
指标UIAbility首次启动

指标UIAbility首次启动时,在指标UIAbility的onWindowStageCreate()生命周期回调中,解析EntryAbility传递过去的want参数,获取到须要加载的页面信息url,传入windowStage.loadContent()办法。

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) => {            // ...        });    }}
指标UIAbility非首次启动

常常还会遇到一类场景,当利用A曾经启动且处于主页面时,回到桌面,关上利用B,并从利用B再次启动利用A,且须要跳转到利用A的指定页面。例如联系人利用和短信利用配合应用的场景。关上短信利用主页,回到桌面,此时短信利用处于已关上状态且以后处于短信利用的主页。再关上联系人利用主页,进入联系人用户A查看详情,点击短信图标,筹备给用户A发送短信,此时会再次拉起短信利用且以后处于短信利用的发送页面。

针对以上场景,即当利用A的UIAbility实例已创立,并且处于该UIAbility实例对应的主页面中,此时,从利用B中须要再次启动利用A的该UIAbility,并且须要跳转到不同的页面,这种状况下要如何实现呢?

  1. 在指标UIAbility中,默认加载的是Index页面。因为以后UIAbility实例之前曾经创立实现,此时会进入UIAbility的onNewWant()回调中且不会进入onCreate()和onWindowStageCreate()生命周期回调,在onNewWant()回调中解析调用方传递过去的want参数,并挂在到全局变量globalThis中,以便于后续在页面中获取。

    import UIAbility from '@ohos.app.ability.UIAbility'export default class FuncAbility extends UIAbility { onNewWant(want, launchParam) {     // 接管调用方UIAbility传过来的参数     globalThis.funcAbilityWant = want;     // ... }}
  2. 在FuncAbility中,此时须要在Index页面中通过页面路由Router模块实现指定页面的跳转,因为此时FuncAbility对应的Index页面是处于激活状态,不会从新变量申明以及进入aboutToAppear()生命周期回调中。因而能够在Index页面的onPageShow()生命周期回调中实现页面路由跳转的性能。

    import router from '@ohos.router';@Entry@Componentstruct Index {  onPageShow() { let funcAbilityWant = globalThis.funcAbilityWant; let url2 = funcAbilityWant?.parameters?.router; if (url2 && url2 === 'funcA') {   router.replaceUrl({     url: 'pages/Second',   }) }  }  // 页面展现  build() { // ...  }}
当被调用方Ability的启动模式设置为standard启动模式时,每次启动都会创立一个新的实例,那么onNewWant()回调就不会被用到。

通过Call调用实现UIAbility交互(仅对系统利用凋谢)

Call调用是UIAbility能力的扩大,它为UIAbility提供一种可能被内部调用并与内部进行通信的能力。Call调用反对前台与后盾两种启动形式,使UIAbility既能被拉起到前台展现UI,也能够在后盾被创立并运行。Call调用在调用方与被调用方间建设了IPC通信,因而利用开发者可通过Call调用实现不同UIAbility之间的数据共享。

Call调用的外围接口是startAbilityByCall办法,与startAbility接口的不同之处在于:

  • startAbilityByCall反对前台与后盾两种启动形式,而startAbility仅反对前台启动。
  • 调用方可应用startAbilityByCall所返回的Caller对象与被调用方进行通信,而startAbilty不具备通信能力。

Call调用的应用场景次要包含:

  • 须要与被启动的UIAbility进行通信。
  • 心愿被启动的UIAbility在后盾运行。

参考

  • https://developer.harmonyos.com/cn/docs/documentation/doc-gui...