开天辟地 HarmonyOS(鸿蒙) - 开发基础: UIAbility 的启动类型

源码 https://github.com/webabcd/HarmonyDemo
作者 webabcd

开天辟地 HarmonyOS(鸿蒙) - 开发基础: UIAbility 的启动类型

示例如下:

pages\basic\LaunchTypeDemo.ets

/*
 * UIAbility 的启动类型 - 共有 3 种(singleton, multiton 或 standard, specified)
 * 需要在 module.json5 配置文件中,通过 abilities 的 launchType 标签指定 UIAbility 的启动类型
 *
 * singleton - 单实例方式,每次打开时如果发现已存在则复用之,即最近任务列表中只会有一个这种类型的实例
 * multiton 或 standard - 多实例方式,每次打开都创建一个新的实例,即最近任务列表中可能会有多个这种类型的实例
 * specified - 指定实例模式,每次打开时,如果发现指定 specified 标识的 UIAbility 已存在则复用之,否则就新建实例
 *   在 HAP 对应的 AbilityStage 中的 onAcceptWant() 中返回 specified 标识
 *   关于 HAP 对应的 AbilityStage 请参见 /entry/src/main/ets/MyAbilityStage.ets 中的代码
 */

import { TitleBar } from '../TitleBar';
import { common, Want } from '@kit.AbilityKit';

@Entry
@Component
struct UIAbilityDemo {

  build() {
    Column() {
      TitleBar()
      Tabs() {
        TabContent() { MySample1() }.tabBar('基础').align(Alignment.Top)
      }
      .scrollable(true)
      .barMode(BarMode.Scrollable)
      .layoutWeight(1)
    }
  }
}

@Component
struct MySample1 {

  context = getContext(this) as common.UIAbilityContext;
  @State message: string = ""

  aboutToAppear(): void {
    this.message = `${LocalStorage.getShared().get("param")}`
  }

  build() {
    Column({ space: 10 }) {

      Text(this.message)

      Button("以 singleton 的方式启动一个 UIAbility").onClick(async () => {
        // Want - 需要拉起的 ability 的相关信息
        let want: Want = {
          bundleName: 'com.webabcd.harmonydemo', // 需要打开的 ability 的 bundle 的名称
          abilityName: 'com.webabcd.harmonydemo.EntryAbility_singleton', // 需要打开的 ability 的名称(此名称是在 module.json5 中配置的)
        };
        // context.startAbility() - 拉起指定的 ability
        await this.context.startAbility(want)
      })

      Button("以 multiton 的方式启动一个 UIAbility").onClick(async () => {
        // Want - 需要拉起的 ability 的相关信息
        let want: Want = {
          bundleName: 'com.webabcd.harmonydemo', // 需要打开的 ability 的 bundle 的名称
          abilityName: 'com.webabcd.harmonydemo.EntryAbility_multiton', // 需要打开的 ability 的名称(此名称是在 module.json5 中配置的)
        };
        // context.startAbility() - 拉起指定的 ability
        await this.context.startAbility(want)
      })

      Button("以 specified 的方式(标识为 abc)启动一个 UIAbility").onClick(async () => {
        // Want - 需要拉起的 ability 的相关信息
        let want: Want = {
          bundleName: 'com.webabcd.harmonydemo', // 需要打开的 ability 的 bundle 的名称
          abilityName: 'com.webabcd.harmonydemo.EntryAbility_specified', // 需要打开的 ability 的名称(此名称是在 module.json5 中配置的)
          parameters: {
            specifiedKey: "abc" // 传参,用于在 module 对应的 AbilityStage 中的 onAcceptWant() 中确定如何返回 specified 标识
          }
        };
        // context.startAbility() - 拉起指定的 ability
        await this.context.startAbility(want)
      })

      Button("以 specified 的方式(标识为 xyz)启动一个 UIAbility").onClick(async () => {
        // Want - 需要拉起的 ability 的相关信息
        let want: Want = {
          bundleName: 'com.webabcd.harmonydemo', // 需要打开的 ability 的 bundle 的名称
          abilityName: 'com.webabcd.harmonydemo.EntryAbility_specified', // 需要打开的 ability 的名称(此名称是在 module.json5 中配置的)
          parameters: {
            specifiedKey: "xyz" // 传参,用于在 module 对应的 AbilityStage 中的 onAcceptWant() 中确定如何返回 specified 标识
          }
        };
        // context.startAbility() - 拉起指定的 ability
        await this.context.startAbility(want)
      })
    }
  }
}

\entry\src\main\ets\entryability\EntryAbility_singleton.ets

/*
 * UIAbility - 用于为应用提供绘制界面的窗口
 * UIAbility 的相关配置,请参见 module.json5 配置文件中的 abilities 标签
 *
 * 本例用于演示 singleton 方式启动的 UIAbility
 */

import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';

export default class EntryAbility2 extends UIAbility {

  param = ""
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    this.param = `abilityName:${want.abilityName ?? ""}`
  }

  onWindowStageCreate(windowStage: window.WindowStage): void {
    let record: Record<string, string> = { 'param': this.param };
    windowStage.loadContent('pages/basic/LaunchTypeDemo', new LocalStorage(record));
  }
}

\entry\src\main\ets\entryability\EntryAbility_multiton.ets

/*
 * UIAbility - 用于为应用提供绘制界面的窗口
 * UIAbility 的相关配置,请参见 module.json5 配置文件中的 abilities 标签
 *
 * 本例用于演示 multiton 方式启动的 UIAbility
 */

import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';

export default class EntryAbility2 extends UIAbility {

  param = ""
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    this.param = `abilityName:${want.abilityName ?? ""}`
  }

  onWindowStageCreate(windowStage: window.WindowStage): void {
    let record: Record<string, string> = { 'param': this.param };
    windowStage.loadContent('pages/basic/LaunchTypeDemo', new LocalStorage(record));
  }
}

\entry\src\main\ets\entryability\EntryAbility_specified.ets

/*
 * UIAbility - 用于为应用提供绘制界面的窗口
 * UIAbility 的相关配置,请参见 module.json5 配置文件中的 abilities 标签
 *
 * 本例用于演示 specified 方式启动的 UIAbility
 */

import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';

export default class EntryAbility2 extends UIAbility {

  param = ""
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    this.param = `abilityName:${want.abilityName ?? ""}, specifiedKey:${want.parameters?.specifiedKey ?? ""}`
  }

  onWindowStageCreate(windowStage: window.WindowStage): void {
    let record: Record<string, string> = { 'param': this.param };
    windowStage.loadContent('pages/basic/LaunchTypeDemo', new LocalStorage(record));
  }
}

\entry\src\main\ets\MyAbilityStage.ets

/*
 * AbilityStage - 每个 HAP 都会对应一个 AbilityStage
 *   AbilityStage 是 HAP 的容器,当需要加载 HAP 的入口 UIAbility 实例时,会先创建 AbilityStage 实例
 * 需要在 module.json5 中的 module 的 srcEntry 中配置对应的 AbilityStage 的代码的地址
 */

import { AbilityConstant, AbilityStage, Configuration, Want } from '@kit.AbilityKit';
import { MyLog } from './utils/MyLog';

export default class MyAbilityStage extends AbilityStage {

  // 创建完成时的回调(注:加载 HAP 的入口 UIAbility 实例之前会先创建 AbilityStage 实例)
  onCreate() {
    MyLog.d('AbilityStage onCreate');

    // AbilityStageContext - AbilityStage 的上下文(在 AbilityStage 内,可以通过 this.context 获取 AbilityStageContext 对象)
    //   currentHapModuleInfo - 当前的 hap 模块信息(一个 HapModuleInfo 对象)
    //     name - 当前的 hap 模块的名称
    //     codePath - 当前的 hap 模块的 .hap 文件的地址
    let abilityStageContext = this.context
    let hapModuleInfo = abilityStageContext.currentHapModuleInfo
    MyLog.d(`AbilityStage mudule name: ${hapModuleInfo.name}`) // 本例为 entry
    MyLog.d(`AbilityStage mudule codePath: ${hapModuleInfo.codePath}`) // 本例为 /data/storage/el1/bundle/entry.hap
  }

  // 当 UIAbility 以 specified 的方式启动时,就会走到 HAP 的对应的 AbilityStage 中的 onAcceptWant() 回调
  onAcceptWant(want: Want): string {
    MyLog.d('AbilityStage onAcceptWant');

    // 返回 specified 标识
    //   如果相同 specified 标识的 UIAbility 已存在,则热启动它(启动已存在的实例)
    //   如果相同 specified 标识的 UIAbility 不存在,则冷启动它(创建新的实例,并启动)
    return `${want.parameters?.specifiedKey ?? ""}`
  }

  // 内存占用级别发生变化时的回调
  // 注:在 UIAbility 中也有此回调
  onMemoryLevel(level: AbilityConstant.MemoryLevel): void {
    // MEMORY_LEVEL_MODERATE - 内存占用适中
    // MEMORY_LEVEL_LOW - 内存占用低
    // MEMORY_LEVEL_CRITICAL - 内存占用高
    MyLog.d(`AbilityStage onMemoryLevel ${level}`);
  }

  // 全局的环境配置发生变化时的回调(比如系统语言,深色浅色模式等)
  // 注:在 UIAbility 中也有此回调
  onConfigurationUpdate(newConfig: Configuration): void {
    MyLog.d(`AbilityStage onConfigurationUpdate ${JSON.stringify(newConfig)}`);
  }
}

源码 https://github.com/webabcd/HarmonyDemo
作者 webabcd

posted @ 2025-03-07 15:26  webabcd  阅读(128)  评论(0)    收藏  举报