UIAbility组件启动模式

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

  • singleton(单实例模式)
  • standard(标准实例模式)
  • specified(指定实例模式)

singleton启动模式

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

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

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

如果需要使用singleton启动模式,在module.json5配置文件中的"launchType"字段配置为"singleton"即可。

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

standard启动模式

standard启动模式为标准实例模式,每次调用startAbility()方法时,都会在应用进程中创建一个新的该类型UIAbility实例。即在最近任务列表中可以看到有多个该类型的UIAbility实例。这种情况下可以将UIAbility配置为standard(标准实例模式)。

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. 在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. 由于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 '';
        }
    }

坚果
74 声望7 粉丝

坚果派联合创始人、华为HDE,OpenHarmony MVP