一、什么是AbilityStage
AbilityStage是一个Module级别的组件容器,应用的HAP在首次加载时会创建一个AbilityStage实例,可以对该Module进行初始化等操作。
AbilityStage与Module一一对应,即一个Module拥有一个AbilityStage。
注意: DevEco Studio默认工程中未自动生成AbilityStage,如需要使用AbilityStage的能力,可以手动新建一个AbilityStage文件。
二、如何应用AbilityStage
1、创建自定义AbilityStage类,实现onCreate等相关方法。
import { AbilityStage, Want } from '@kit.AbilityKit';
export default class MyAbilityStage extends AbilityStage {
onCreate(): void {
// 应用的HAP在首次加载的时,为该Module初始化操作
}
onAcceptWant(want: Want): string {
// 仅specified模式下触发
return 'MyAbilityStage';
}
onMemoryLevel(level: AbilityConstant.MemoryLevel): void {
// 根据系统可用内存的变化情况,释放不必要的内存
}
}
2、在module.json5配置文件中,通过配置 srcEntry 参数来指定模块对应的代码路径,以作为HAP加载的入口。
{
"module": {
"name": "entry",
"type": "entry",
"srcEntry": "./ets/myabilitystage/MyAbilityStage.ets",
// ...
}
}
3、相关回调
AbilityStage拥有onCreate()生命周期回调和onAcceptWant()、onConfigurationUpdated()、onMemoryLevel()事件回调。
- onCreate()生命周期回调:在开始加载对应Module的第一个UIAbility实例之前会先创建AbilityStage,并在AbilityStage创建完成之后执行其onCreate()生命周期回调。AbilityStage模块提供在Module加载的时候,通知开发者,可以在此进行该Module的初始化(如资源预加载,线程创建等)能力。
- onAcceptWant()事件回调:UIAbility指定实例模式(specified)启动时候触发的事件回调,具体使用请参见UIAbility启动模式综述。
- onConfigurationUpdated()事件回调:当系统全局配置发生变更时触发的事件,系统语言、深浅色等,配置项目前均定义在Configuration类中。
- onMemoryLevel()事件回调:当系统调整内存时触发的事件。
三、UIAbility 组件的启动模式
UIAbility的启动模式是指UIAbility实例在启动时的不同呈现状态。针对不同的业务场景,系统提供了三种启动模式:
1、singleton启动模式
singleton启动模式为单实例模式,也是默认情况下的启动模式。 每次调用startAbility()方法时,如果应用进程中该类型的UIAbility实例已经存在,则复用系统中的UIAbility实例。系统中只存在唯一一个该UIAbility实例,即在最近任务列表中只存在一个该类型的UIAbility实例。
如果需要使用singleton启动模式,在module.json5配置文件中的launchType字段配置为singleton即可。
2、multiton启动模式
multiton启动模式为多实例模式,每次调用startAbility()方法时,都会在应用进程中创建一个新的该类型UIAbility实例。即在最近任务列表中可以看到有多个该类型的UIAbility实例。这种情况下可以将UIAbility配置为multiton(多实例模式)。
multiton启动模式的开发使用,在module.json5配置文件中的launchType字段配置为multiton即可。
{
"module": {
// ...
"abilities": [
{
"launchType": "multiton",
// ...
}
]
}
}
3、specified启动模式
specified启动模式为指定实例模式,针对一些特殊场景使用(例如文档应用中每次新建文档希望都能新建一个文档实例,重复打开一个已保存的文档希望打开的都是同一个文档实例)。 如果需要使用该模式,则需要进行以下步骤:
3.1在SpecifiedAbility中,将module.json5配置文件的launchType字段配置为specified。
{
"module": {
// ...
"abilities": [
{
"launchType": "specified",
// ...
}
]
}
}
3.2在创建UIAbility实例之前,开发者可以为该实例指定一个唯一的字符串Key,这样在调用startAbility()方法时,应用就可以根据指定的Key来识别响应请求的UIAbility实例。在EntryAbility中,调用startAbility()方法时,可以在want参数中增加一个自定义参数,例如instanceKey,以此来区分不同的UIAbility实例。
let want: Want = {
deviceId: '', // deviceId为空表示本设备
bundleName: 'com.samples.stagemodelabilitydevelop',
abilityName: 'SpecifiedFirstAbility',
moduleName: 'entry', // moduleName非必选
parameters: {
// 自定义信息
instanceKey: this.KEY_NEW
}
}
3.3由于SpecifiedAbility的启动模式被配置为指定实例启动模式,因此在SpecifiedAbility启动之前,会先进入对应的AbilityStage的onAcceptWant()生命周期回调中,以获取该UIAbility实例的Key值。然后系统会自动匹配,如果存在与该UIAbility实例匹配的Key,则会启动与之绑定的UIAbility实例,并进入该UIAbility实例的onNewWant()回调函数;否则会创建一个新的UIAbility实例,并进入该UIAbility实例的onCreate()回调函数和onWindowStageCreate()回调函数。
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';
}
}
四、UIAbility 组件间的交互
1、唤起Ability
注意:在被拉起的Ability中,可以通过获取传递过来的want参数的parameters来获取拉起方UIAbility的PID、Bundle Name等信息。
2、停止Ability
在被拉起的AbilityTemp业务完成之后,如需要停止当前AbilityTemp实例,在AbilityTemp中通过调用terminateSelf()方法实现。
注意: 调用terminateSelf()方法停止当前UIAbility实例时,默认会保留该实例的快照(Snapshot),即在最近任务列表中仍然能查看到该实例对应的任务。如不需要保留该实例的快照,可以在其对应UIAbility的module.json5配置文件中,将abilities标签的removeMissionAfterTerminate字段配置为true。
2.1 --如需要关闭应用所有的UIAbility实例,可以调用ApplicationContext的killAllProcesses()方法实现关闭应用所有的进程。
3、启动应用内的UIAbility并获取返回结果
在一个EntryAbility启动另外一个FuncAbility时,希望在被启动的FuncAbility完成相关业务后,能将结果返回给调用方。
3.1在EntryAbility中,调用startAbilityForResult()接口启动FuncAbility,异步回调中的data用于接收FuncAbility停止自身后返回给EntryAbility的信息。示例中的context的获取方式请参见获取UIAbility的上下文信息。
import { common, Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { promptAction } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';
const TAG: string = '[Page_UIAbilityComponentsInteractive]';
const DOMAIN_NUMBER: number = 0xFF00;
@Entry
@Component
struct Page_UIAbilityComponentsInteractive {
build() {
Column() {
//...
List({ initialIndex: 0 }) {
ListItem() {
Row() {
//...
}
.onClick(() => {
let context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext; // UIAbilityContext
const RESULT_CODE: number = 1001;
let want: Want = {
deviceId: '', // deviceId为空表示本设备
bundleName: 'com.samples.stagemodelabilitydevelop',
moduleName: 'entry', // moduleName非必选
abilityName: 'FuncAbilityA',
parameters: {
// 自定义信息
info: '来自EntryAbility UIAbilityComponentsInteractive页面'
}
};
//以下为获取返回结果的代码 ------------------
context.startAbilityForResult(want).then((data) => {
if (data?.resultCode === RESULT_CODE) {
// 解析被调用方UIAbility返回的信息
let info = data.want?.parameters?.info;
hilog.info(DOMAIN_NUMBER, TAG, JSON.stringify(info) ?? '');
if (info !== null) {
promptAction.showToast({
message: JSON.stringify(info)
});
}
}
hilog.info(DOMAIN_NUMBER, TAG, JSON.stringify(data.resultCode) ?? '');
}).catch((err: BusinessError) => {
hilog.error(DOMAIN_NUMBER, TAG, `Failed to start ability for result. Code is ${err.code}, message is ${err.message}`);
});
})
}
}
}
}
}
3.2在FuncAbility停止自身时,需要调用terminateSelfWithResult()方法,入参abilityResult为FuncAbility需要返回给EntryAbility的信息。
import { common } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
const TAG: string = '[Page_FuncAbilityA]';
const DOMAIN_NUMBER: number = 0xFF00;
@Entry
@Component
struct Page_FuncAbilityA {
build() {
Column() {
//...
List({ initialIndex: 0 }) {
ListItem() {
Row() {
//...
}
.onClick(() => {
let context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext; // UIAbilityContext
const RESULT_CODE: number = 1001;
let abilityResult: common.AbilityResult = {
resultCode: RESULT_CODE,
want: {
bundleName: 'com.samples.stagemodelabilitydevelop',
moduleName: 'entry', // moduleName非必选
abilityName: 'FuncAbilityB',
parameters: {
info: '来自FuncAbility Index页面'
},
},
};
context.terminateSelfWithResult(abilityResult, (err) => {
if (err.code) {
hilog.error(DOMAIN_NUMBER, TAG, `Failed to terminate self with result. Code is ${err.code}, message is ${err.message}`);
return;
}
});
})
}
}
}
}
}