HarmonyOS:UIAbility组件启动模式

一、概述

UIAbility的启动模式是指UIAbility实例在启动时的不同呈现状态。针对不同的业务场景,系统提供了三种启动模式:

  • singleton(单实例模式)
  • multiton(多实例模式)
  • specified(指定实例模式)
    说明 standard是multiton的曾用名,效果与多实例模式一致。

二、singleton启动模式

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

每次调用startAbility()方法时,如果应用进程中该类型的UIAbility实例已经存在,则复用系统中的UIAbility实例。系统中只存在唯一一个该UIAbility实例,即在最近任务列表中只存在一个该类型的UIAbility实例。
在@Entry组件里调用startAbility方法

bash 复制代码
 Button() {
          Text('启动 SingletonAbility ')
            .fontSize(24)
            .fontWeight(FontWeight.Normal)
            .fontColor('#000')
        }
        .type(ButtonType.Capsule)
        .margin({ top: 20 })
        .backgroundColor('#ff004bf0')
        .width('90%')
        .height('5%')
        .onClick(() => {
          //// context为调用方UIAbility的UIAbilityContext;
          let context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
          let want: Want = {
            deviceId: '', // deviceId为空表示本设备
            bundleName: 'com.example.learnharmonyos',
            abilityName: 'SingletonAbility',
            moduleName: 'entry', // moduleName非必选

          }
          context.startAbility(want).then(() => {
            hilog.info(DOMAIN_NUMBER, TAG,'Succeeded in starting SingletonAbility.')
          }).catch((err: BusinessError) => {
            hilog.error(DOMAIN_NUMBER, TAG,
              `Failed to start SingletonAbility. Code is ${err.code}, message is ${err.message}`)
          })
        })

单实例模式演示效果图

执行startAbility方法前
执行startAbility方法后
执行手机返回事件后的Ability回调对应的生命周期
再次执行startAbility方法后 SingletonAbility 回调了onNewWant 和 onForeground方法
说明 应用的UIAbility实例已创建,该UIAbility配置为单实例模式,再次调用startAbility()方法启动该UIAbility实例。由于启动的还是原来的UIAbility实例,并未重新创建一个新的UIAbility实例,此时只会进入该UIAbility的 onNewWant()回调,不会进入其onCreate()和onWindowStageCreate()生命周期回调。
如果需要使用singleton启动模式,在module.json5配置文件中的launchType字段配置为singleton即可。

bash 复制代码
{
  "module": {
    // ...
    "abilities": [
       {
        "name": "SingletonAbility",
        "srcEntry": "./ets/entryability/SingletonAbility.ets",
        "description": "$string:SingletonAbility_desc",
        "icon": "$media:layered_image",
        "label": "$string:SingletonAbility_label",
        // 启动模式:单例模式
        "launchType": "singleton",
        "startWindowIcon": "$media:startIcon",
        "startWindowBackground": "$color:start_window_background"
      }
    ]
  }
}

三、multiton启动模式

multiton启动模式为多实例模式,每次调用startAbility()方法时,都会在应用进程中创建一个新的该类型UIAbility实例。即在最近任务列表中可以看到有多个该类型的UIAbility实例。这种情况下可以将UIAbility配置为multiton(多实例模式)。
multiton启动模式的开发使用,在module.json5配置文件中的launchType字段配置为multiton即可。

多实例模式演示效果

bash 复制代码
{
  "module": {
    // ...
    "abilities": [
       {
        "name": "MultitonAbility",
        "srcEntry": "./ets/entryability/MultitonAbility.ets",
        "description": "$string:MultitonAbility_desc",
        "icon": "$media:layered_image",
        "label": "$string:MultitonAbility_label",
//        multiton启动模式为多实例模式
        "launchType": "multiton",
        "startWindowIcon": "$media:startIcon",
        "startWindowBackground": "$color:start_window_background"
      }
    ]
  }
}

四、specified启动模式

specified启动模式为指定实例模式,针对一些特殊场景使用(例如文档应用中每次新建文档希望都能新建一个文档实例,重复打开一个已保存的文档希望打开的都是同一个文档实例)。
例如有两个UIAbility:EntryAbility和SpecifiedAbility,SpecifiedAbility配置为指定实例模式启动,需要从EntryAbility的页面中启动SpecifiedAbility。
效果图
1.在SpecifiedAbility中,将module.json5配置文件的launchType字段配置为specified。

bash 复制代码
{
  "module": {
    // ...
    "abilities": [
      {
        "name": "SpecifiedAbility",
        "srcEntry": "./ets/specifiedability/SpecifiedAbility.ets",
        "description": "$string:SpecifiedAbility_desc",
        "icon": "$media:layered_image",
        "label": "$string:SpecifiedAbility_label",
        "launchType": "specified",
        "startWindowIcon": "$media:startIcon",
        "startWindowBackground": "$color:start_window_background"
      }
    ]
  }
}

2.在创建UIAbility实例之前,开发者可以为该实例指定一个唯一的字符串Key,这样在调用startAbility()方法时,应用就可以根据指定的Key来识别响应请求的UIAbility实例。在EntryAbility中,调用startAbility()方法时,可以在want参数中增加一个自定义参数,例如instanceKey,以此来区分不同的UIAbility实例。

bash 复制代码
 // 在启动指定实例模式的UIAbility时,给每一个UIAbility实例配置一个独立的Key标识
 // 例如在文档使用场景中,可以用文档路径作为Key标识
 import { common, Want } from '@kit.AbilityKit';
 import { hilog } from '@kit.PerformanceAnalysisKit';
 import { BusinessError } from '@kit.BasicServicesKit';

 const TAG: string = '[Page_StartModel]';
 const DOMAIN_NUMBER: number = 0xFF00;

 function getInstance(): string {
   return 'KEY';
 }

 @Entry
 @Component
 struct Page_StartModel {
   private KEY_NEW = 'KEY';

   build() {
     Row() {
       Column() {
         // ...
         Button()// ...
           .onClick(() => {
             let context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
             // context为调用方UIAbility的UIAbilityContext;
             let want: Want = {
               deviceId: '', // deviceId为空表示本设备
               bundleName: 'com.samples.stagemodelabilitydevelop',
               abilityName: 'SpecifiedFirstAbility',
               moduleName: 'entry', // moduleName非必选
               parameters: {
                 // 自定义信息
                 instanceKey: this.KEY_NEW
               }
             };
             context.startAbility(want).then(() => {
               hilog.info(DOMAIN_NUMBER, TAG, 'Succeeded in starting SpecifiedAbility.');
             }).catch((err: BusinessError) => {
               hilog.error(DOMAIN_NUMBER, TAG, `Failed to start SpecifiedAbility. Code is ${err.code}, message is ${err.message}`);
             })
             this.KEY_NEW = this.KEY_NEW + 'a';
           })
         // ...
         Button()// ...
           .onClick(() => {
             let context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
             // context为调用方UIAbility的UIAbilityContext;
             let want: Want = {
               deviceId: '', // deviceId为空表示本设备
               bundleName: 'com.samples.stagemodelabilitydevelop',
               abilityName: 'SpecifiedSecondAbility',
               moduleName: 'entry', // moduleName非必选
               parameters: {
                 // 自定义信息
                 instanceKey: getInstance()
               }
             };
             context.startAbility(want).then(() => {
               hilog.info(DOMAIN_NUMBER, TAG, 'Succeeded in starting SpecifiedAbility.');
             }).catch((err: BusinessError) => {
               hilog.error(DOMAIN_NUMBER, TAG, `Failed to start SpecifiedAbility. Code is ${err.code}, message is ${err.message}`);
             })
             this.KEY_NEW = this.KEY_NEW + 'a';
           })
         // ...
       }
       .width('100%')
     }
     .height('100%')
   }
 }

3.由于SpecifiedAbility的启动模式被配置为指定实例启动模式,因此在SpecifiedAbility启动之前,会先进入对应的AbilityStage的onAcceptWant()生命周期回调中,以获取该UIAbility实例的Key值。然后系统会自动匹配,如果存在与该UIAbility实例匹配的Key,则会启动与之绑定的UIAbility实例,并进入该UIAbility实例的onNewWant()回调函数;否则会创建一个新的UIAbility实例,并进入该UIAbility实例的onCreate()回调函数和onWindowStageCreate()回调函数。

示例代码中,通过实现onAcceptWant()生命周期回调函数,解析传入的want参数,获取自定义参数instanceKey。业务逻辑会根据这个参数返回一个字符串Key,用于标识当前UIAbility实例。如果返回的Key已经对应一个已启动的UIAbility实例,系统会将该UIAbility实例拉回前台并获焦,而不会创建新的实例。如果返回的Key没有对应已启动的UIAbility实例,则系统会创建新的UIAbility实例并启动。

bash 复制代码
 import { AbilityStage, Want } from '@kit.AbilityKit';

 export default class MyAbilityStage extends AbilityStage {
   onAcceptWant(want: Want): string {
     // 在被调用方的AbilityStage中,针对启动模式为specified的UIAbility返回一个UIAbility实例对应的一个Key值
     // 当前示例指的是module1 Module的SpecifiedAbility
     if (want.abilityName === 'SpecifiedFirstAbility' || want.abilityName === 'SpecifiedSecondAbility') {
       // 返回的字符串Key标识为自定义拼接的字符串内容
       if (want.parameters) {
         return `SpecifiedAbilityInstance_${want.parameters.instanceKey}`;
       }
     }
     // ...
     return 'MyAbilityStage';
   }
 }

说明

  1. 当应用的UIAbility实例已经被创建,并且配置为指定实例模式时,如果再次调用startAbility()方法启动该UIAbility实例,且AbilityStage的onAcceptWant()回调匹配到一个已创建的UIAbility实例,则系统会启动原来的UIAbility实例,并且不会重新创建一个新的UIAbility实例。此时,该UIAbility实例的onNewWant()回调会被触发,而不会触发onCreate()和onWindowStageCreate()生命周期回调。
  2. DevEco Studio默认工程中未自动生成AbilityStage,AbilityStage文件的创建请参见AbilityStage组件容器
相关推荐
一梦南柯3 小时前
HarmonyOS NEXT快速入手IBest-UI组件库
harmonyos
二流小码农4 小时前
鸿蒙开发:权限管理之权限声明
android·ios·harmonyos
全栈若城7 小时前
67.Harmonyos NEXT 图片预览组件之性能优化策略
性能优化·harmonyos·harmonyos next
觉醒法师7 小时前
HarmonyOS NEXT - 电商App实例三( 网络请求axios)
前端·华为·typescript·axios·harmonyos·ark-ts
全栈若城10 小时前
63.Harmonyos NEXT 图片预览组件之手势处理实现
华为·harmonyos·harmonyos next
Bowen_J11 小时前
HarmonyOS架构详解
华为·harmonyos·arkts
蓝枫Amy11 小时前
HarmonyOS应用程序包概述
程序员·harmonyos
轻口味11 小时前
【每日学点HarmonyOS Next知识】状态栏字体、生命周期、自定义对话框屏幕中间、透明度、tab居中
pytorch·华为·harmonyos·harmonyosnext
林钟雪11 小时前
HarmonyNext实战:基于ArkTS的高性能图像处理应用开发
harmonyos