【鸿蒙开发】第十四章 Stage模型应用组件-任务Mission

1 任务(Mission)管理场景

任务(Mission)管理相关的基本概念如下:

  • AbilityRecord :系统服务侧管理一个UIAbility实例的最小单元,对应一个应用侧的UIAbility组件实例。系统服务侧管理UIAbility实例数量上限为512个。

  • MissionRecord :任务管理的最小单元。一个MissionRecord中仅有一个AbilityRecord,即一个UIAbility组件实例对应一个单独的任务。

  • MissionList:一个从桌面开始启动的任务列表,记录了任务之间的启动关系,下一个任务由上一个任务启动,最底部的任务由桌面启动,这里称之为任务链。

  • MissionListManager :系统任务管理模块,内部维护了当前所有的任务链,与最近任务列表保持一致。

    任务的管理由系统应用(如桌面应用)负责,三方应用无法管理任务。用户通过最近任务列表进行任务的相关交互。当创建任务后,用户可以对最近任务列表进行如下操作:

  • 删除一个指定的任务。

  • 加锁或解锁一个指定的任务(加锁后的任务在清理所有任务时不会被清理)。

  • 清理最近任务列表中的所有任务。

  • 将一个指定的任务切换到前台。

一个UIAbility实例对应一个单独的任务,因此应用调用startAbility()方法启动一个UIAbility时,就是创建了一个任务。

  1. 桌面应用调用missionManager的接口管理任务,需要申请ohos.permission.MANAGE_MISSIONS权限,配置方式请参见配置文件权限声明。
  2. 利用missionManager进行任务管理(监听任务变化、获取任务信息、获取任务快照、清理任务、任务加锁/解锁等)。
typescript 复制代码
import missionManager from '@ohos.app.ability.missionManager'
import { BusinessError } from '@ohos.base';

let listener: missionManager.MissionListener = {
  // 任务创建
  onMissionCreated: (mission) => {
    console.info("--------onMissionCreated-------")
  },
  // 任务销毁
  onMissionDestroyed: (mission) => {
    console.info("--------onMissionDestroyed-------")
  },
  // 任务快照变化
  onMissionSnapshotChanged: (mission) => {
    console.info("--------onMissionSnapshotChanged-------")
  },
  // 任务被移动到前台
  onMissionMovedToFront: (mission) => {
    console.info("--------onMissionMovedToFront-------")
  },
  // 任务图标变化
  onMissionIconUpdated: (mission, icon) => {
    console.info("--------onMissionIconUpdated-------")
  },
  // 任务名称变化
  onMissionLabelUpdated: (mission) => {
    console.info("--------onMissionLabelUpdated-------")
  },
  // 任务实例被关闭
  onMissionClosed: (mission) => {
    console.info("--------onMissionClosed-------")
  }
};

// 1.注册任务变化通知
let listenerId = missionManager.on('mission', listener);

// 2.获取系统最近20个任务
missionManager.getMissionInfos("", 20, (error, missions) => {
  console.info("getMissionInfos is called, error.code = " + error.code);
  console.info("size = " + missions.length);
  console.info("missions = " + JSON.stringify(missions));
});

// 3.获取单个任务的详细信息()
let missionId = 11; // 11只是示例,实际是从系统中获取的任务id,下面类似
let mission = missionManager.getMissionInfo("", missionId).catch((err: BusinessError) => {
  console.info('${err.code}');
});

// 4.获取任务快照
missionManager.getMissionSnapShot("", missionId, (error, snapshot) => {
  console.info("getMissionSnapShot is called, error.code = " + error.code);
  console.info("bundleName = " + snapshot.ability.bundleName);
})

// 5.获取低分辨任务快照
missionManager.getLowResolutionMissionSnapShot("", missionId, (error, snapshot) => {
  console.info("getLowResolutionMissionSnapShot is called, error.code = " + error.code);
  console.info("bundleName = " + snapshot.ability.bundleName);
})

// 6.加锁/解锁任务
missionManager.lockMission(missionId).then(() => {
  console.info("lockMission is called ");
});

missionManager.unlockMission(missionId).then(() => {
  console.info("unlockMission is called ");
});

// 7.把任务切到前台
missionManager.moveMissionToFront(missionId).then(() => {
  console.info("moveMissionToFront is called ");
});

// 8.删除单个任务
missionManager.clearMission(missionId).then(() => {
  console.info("clearMission is called ");
});

// 9.删除全部任务
missionManager.clearAllMissions().catch((err: BusinessError) => {
  console.info('${err.code}');
});

// 10.解注册任务变化通知
missionManager.off('mission', listenerId, (error) => {
  console.info("unregisterMissionListener");
})

2 任务(Mission)与启动模式

如前文所述,一个UIAbility实例对应一个任务。UIAbility实例个数与UIAbility配置的启动模式有关。在FA模型下,通过config.json配置文件中的"launchType"属性配置;在Stage模型下,通过module.json5配置文件中的"launchType"属性配置。

下面介绍了任务管理如何实现以下三种启动模式UIAbility组件的管理:

2.1 singleton单实例模式

应用在运行时只存在一个该UIAbility实例。

2.2 multiton多实例模式

每次调用startAbility()方法,都会在应用进程中创建一个该UIAbility实例。

2.3 specified指定实例模式

AbilityStage的(onAcceptWant())决定是否创建新的UIAbility实例。

每个UIAbility实例都对应了一个最近任务列表中看到的Mission(任务)。

每个UIAbility实例对应的Mission都保留有该UIAbility实例的快照(Snapshot)UIAbility实例销毁后,Mission信息(包括UIAbility信息和任务快照)依然会保留,直到用户删除该任务。

3 页面栈及任务链

3.1 页面栈

单个UIAbility组件可以实现多个页面,并在多个页面之间跳转,这种UIAbility组件内部的页面跳转关系称为"页面栈",由ArkUI框架统一管理,如下图中:
UIAbility1Page1->Page2->Page3
UIAbility2PageA->PageB->PageC

  • 页面栈的形成(下面2/3/5/6步骤为页面跳转,由ArkUI管理)
  1. 点击桌面图标(startAbility)启动UIAbility1UIAbility1的初始页面为Page1
  2. 点击Page1页面按钮(Navigator)跳转到Page2页面。
  3. 点击Page2页面按钮(Navigator)跳转到Page3页面。
  4. 点击Page3页面按钮(startAbility)跳转到UIAbility2UIAbility2的初始页面为PageA
  5. 点击PageA页面按钮(Navigator)跳转到PageB页面。
  6. 点击PageB页面按钮(Navigator)跳转到PageC页面。
  • 页面栈的返回(下面1/2/4/5步骤为页面跳转,由ArkUI管理)
  1. UIAbility2PageC页面点击返回键回到UIAbility2PageB页面。
  2. UIAbility2PageB页面点击返回键回到UIAbility2PageA页面。
  3. UIAbility2PageA页面点击返回键跳转到UIAbility1Page3页面。
  4. UIAbility1Page3页面点击返回键回到UIAbility1Page2页面。
  5. UIAbility1Page2页面点击返回键回到UIAbility1Page1页面。
  6. UIAbility1Page1页面点击返回键回到桌面

3.2 任务链

上文介绍了页面栈的返回,如果Ability2页面栈一层层通过返回键返回到最底层,再次点击返回键时,会返回到Ability1。因为在MissionList中记录了任务(Mission)之间的启动关系,即如果Ability1通过startAbility启动Ability2,则会形成一个MissionList任务链Ability1->Ability2,当Ability2页面栈返回到首页时,再次点击返回键,会返回到Ability1的页面。

MissionList任务链记录了任务之间的拉起关系,但是这个任务链可能会断开,有以下几种情况会导致任务链的断开:

  1. 进入任务列表,把任务链中间某个任务移动到前台。
  2. 进入任务列表,把任务链中间某个任务清理掉。
  3. 单实例UIAbility的任务,被不同的任务(包括Ability或桌面)反复拉起(AbilityB为单例)。

4 设置任务快照的图标和名称

设置任务快照的图标和名称是为了提高用户界面的可视化性和用户体验,以便更好地管理和跟踪应用程序中的任务和功能。通过为每个任务快照设置不同的图标名称,可以更轻松地区分和识别每个任务的功能。

默认情况下任务快照的图标和名称采用的是module.json5配置文件的abilities标签中的iconlabel字段,如下图所示。

也可以使用UIAbilityContext.setMissionIcon()UIAbilityContext.setMissionLabel()方法,根据需要自定义任务快照的图标和名称。例如,对于UIAbility的多实例启动模式,可以根据不同的功能配置相应的任务快照的图标名称

4.1 设置任务快照的图标(仅对系统应用开放)

通过调用UIAbilityContext.setMissionIcon()方法修改任务快照的图标。

typescript 复制代码
import common from '@ohos.app.ability.common';
import { BusinessError } from '@ohos.base';

let context: common.UIAbilityContext = ...; // UIAbilityContext
let pixelMap: PixelMap = ...; // 图片的PixelMap信息

context.setMissionIcon(pixelMap, (err: BusinessError) => {
  if (err.code) {
    console.error(`Failed to set mission icon. Code is ${err.code}, message is ${err.message}`);
  }
})

4.2 设置任务快照的名称

通过调用UIAbilityContext.setMissionLabel()方法修改任务快照的名称。

typescript 复制代码
import common from '@ohos.app.ability.common';
import { BusinessError } from '@ohos.base';

let context: common.UIAbilityContext = this.context; // UIAbilityContext

context.setMissionLabel('test').then(() => {
  console.info('Succeeded in seting mission label.');
}).catch((err: BusinessError) => {
  console.error(`Failed to set mission label. Code is ${err.code}, message is ${err.message}`);
});
相关推荐
zhanshuo7 小时前
在鸿蒙里优雅地处理网络错误:从 Demo 到实战案例
harmonyos
zhanshuo7 小时前
在鸿蒙中实现深色/浅色模式切换:从原理到可运行 Demo
harmonyos
whysqwhw13 小时前
鸿蒙分布式投屏
harmonyos
whysqwhw14 小时前
鸿蒙AVSession Kit
harmonyos
whysqwhw16 小时前
鸿蒙各种生命周期
harmonyos
whysqwhw17 小时前
鸿蒙音频编码
harmonyos
whysqwhw17 小时前
鸿蒙音频解码
harmonyos
whysqwhw17 小时前
鸿蒙视频解码
harmonyos
whysqwhw17 小时前
鸿蒙视频编码
harmonyos
ajassi200017 小时前
开源 Arkts 鸿蒙应用 开发(十八)通讯--Ble低功耗蓝牙服务器
华为·开源·harmonyos