UIAbility进阶
基本概念
UIAbility组件:是一种包含UI的应用组件,主要用于和用户交互。
ExtensionAbility组件:是基于特定场景(例如服务卡片、输入法等)提供的应用组件。每个具体场景对应一个ExtensionAbilityType,开发者只能使用系统已定义的类型。
HAP:应用安装的基本单位,一个APP可以包含一个或多个HAP。
AbilityStage:Module级别的组件容器,与HAP是一 一对应的关系
AbilityStage组件容器
AbilityStage的定义和能力
AbilityStage是Module级别的组件容器,是HAP的运行期类,应用的HAP在首次加载时会创建一个AbilityStage实例,可以对该Module进行初始化等操作。
AbilityStage与Module一一对应,即一个Module拥有一个AbilityStage。
最主要的能力是初始化模块,以及对以指定实例模式启动的UIAbility组件进行匹配处理。
系统提供了4个回调函数供开发者使用其能力:
onCreate()
:AbilityStage实例创建完成之后触发的回调函数,可以再次进行该Module的初始化(如资源预加载,线程创建等)能力onAcceptWant()
:指定实例模式的UIAbility启动时触发的回调函数onConfigurationUpdated()
:系统发生全局配置变化时的回调函数,如系统语言、深浅色等,配置项目目前均定义在Configuration类中。onMemoryLevel()
:系统决定调整内存时的回调函数。
应用被切换到后台时,系统会将在后台的应用保留在缓存中。即使应用处于缓存中,也会影响系统整体性能。当系统资源不足时,系统会通过多种方式从应用中回收内存,必要时会完全停止应用,从而释放内存用于执行关键任务。为了进一步保持系统内存的平衡,避免系统停止用户的应用进程,可以在AbilityStage中的onMemoryLevel()生命周期回调中订阅系统内存的变化情况,释放不必要的资源。
AbilityStage的创建与使用
DevEco Studio默认工程中未自动生成AbilityStage,如需要使用AbilityStage的能力,可以手动新建一个AbilityStage文件,具体步骤如下:
- 新建AbilityStage目录:在工程Module对应的ets目录下,右键选择"New > Directory",新建一个目录并命名为myabilitystage
- 新建AbilityStage文件
- 自定义继承AbilityStage的类:在MyAbilityStage.ets文件中自定义类继承AbilityStage并加上需要的生命周期回调
export default class MyAbilityStage extends AbilityStage
{
onCreate() {
// HAP在首次加载的时候执行,可以在此函数中为该Module做初始化操作
...
}
onAcceptWant(want: Want) {
// UIAbility组件指定实例启动模式下触发,返回的字符串为UIAbility实例的唯一标识。
...
return 'specifiedUIAbilityInstanceKey'
}
}
- 配置HAP加载入口:在module.json5配置文件中,通过配置srcEntry参数来指定模块对应的代码路径,以作为HAP加载的入口。
{
"module": {
"name": "entry",
"type": "entry",
"srcEntry": "./ets/myabilitystage/MyAbilityStage.ets",
...
}
}
UIAbility组件的启动模式
UIAbility组件单实例启动模式开发
被调用方module.json5配置文件
{
"module": {
...
"abilities":[
{
...
// 设置为单实例模式
"launchType": "singleton"
}
]
}
}
UIAbility组件单实例启动模式执行过程
将第一次启动称为冷启动
UIAbility组件多实例启动模式开发
{
"module": {
...
"abilities":[
{
...
// 设置为多实例实例模式
"launchType": "multiton"
}
]
}
}
UIAbility组件多实例启动模式执行过程
UIAbility组件指定实例启动模式场景
UIAbility组件指定实例启动模式开发
- 被调用方SpecifiedAbility的module.json5配置文件
{
"module": {
...
"abilities": [
{
...
"name": "SpecifiedAbility",
// 设置为指定实例启动模式
"launchType": "specified"
}
]
}
}
- 调用方启动SpecifiedAbility的函数逻辑
// 1.获取UIAbility
let context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
// 为每个UIAbility实例配置唯一key标识,如文档应用中可以使用文档路径和文档名作为key值
function getInstanceKey(path: string) { ... }
// 2.创建Want
let want: Want = {
//指定需要启动的UIAbiltiy组件名
abilityName: 'SpecifiedAbility',
parameters: {
自定义key值,用于标识拉起的UIAbility
instanceKey: this.getInstanceKey(path)
}
}
// 3. 拉起UIAbiltiy
context.startAbility(want).then(() => {
// 启动成功
}).catch((err: BusinessError)=> {
//启动失败
})
- 被调用方SpecifiedAbility对应的AbilityStage文件
export default class MyAbilityStage extends AbilityStage {
...
onAcceptWant(want: Want): string {
if(want.abilityName == 'SpecifiedAbility') {
return want.parameters?.instanceKey.toString();
}
return "";
}
}
UIAbiltiy组件指定实例启动模式执行过程
UIAbility组件间交互
UIAbility组件间交互载体:Want
Want是对象间信息传递的载体吗,用于在应用组件之间传递信息,其使用场景之一是作为startAbility的参数,当UIAbilityA需要启动并需要传递一些数据给UIAbilityB时,Want可以作为一个载体将数据传递给UIAbilityB
Want启动UIAbility组件的两种形式
显示Want启动
- 启动某个明确UIAbility组件时使用
- 需要在Want参数中设置启动的应用包名和UIAbility组件名
隐式Want启动
- 需要使用某个应用的能力,不关心提供能力的具体应用时使用
- 不在Want参数中设置启动的UIAbility组件名
- 需要在Want中设置UIAbility组件的匹配条件
- 系统根据匹配条件提供命中因公供用户选择
显示Want启动UIAbility组件开发
- 调用方页面
// 获取UIAbilityContext
let context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
// 创建Want
let want: Want = {
//指定拉起的应用所在设备,deviceId为空表示本设备
deviced: '',
// 指定拉起的应用包名
bundleName: 'com.example.myapplication',
// 指定拉起的Ability名
abilityName: 'func',
// 自定义信息
parameters: {
info: '来自EntryAbility Index页面'
}
}
// 根据Want拉起对应Ability
context.startAbility(want).then(() => {
//启动成功
}).catch((err: BusinessError) => {
//启动失败
})
- 被调用方UIAbility文件
export default class FuncAbility extends UIAbility {
...
// 接收Want,获取调用方信息
onCreate(want: Want) {
// 接收调用方UIAbility传过来的参数
let info = want.parameters?.info
}
}
隐式Want启动UIAbility组件开发——启动浏览器
- 设置被调用方的module.json5配置文件
{
"module": {
"abilities": [
{
...
"skills": [
{
//设置UIAbility支持的能力类型,如浏览器类型
"entities":[
...
"entry.system.browsable"
],
// 设置UIAbility支持的操作,如查看数据
"actions": [
...
"ohos.want.action.viewData"
]
}
]
}
]
}
}
- 调用方页面
// 获取UIAbilityContext
let context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
// 创建Want,设置action和entities匹配条件
let want: Want = {
action: 'ohos.want.action.viewData',
entities: ['entry.system.browsable'],
uri:'https://www.huawei.com/cn/'
}
// 拉起UIAbility,系统按Want匹配条件启动UIAbility
context.startAbility(want).then(() => {
// 启动成功
}).catch((err: BusinessError) => {
// 启动失败
})
说明:
- 调用方want中设置的action和entities为被调用方module.json5文件中skills中对应字段的子集时,匹配成功。
- 若只匹配到一个应用则直接拉起应用,若匹配多个应用系统弹出多个应用供用户选择。