基本概念
UIAbility组件是一种包含UI的应用组件,主要用于和用户交互。
在项目创建时,系统默认生成的EntryAbility类继承了UIAbility类。
ExtensionAbility组件:是基于特定场景(例如服务卡片、输入法等)提供的应用组件。每一个具体场景对应一个ExtensionAbilityType,开发者只能使用系统已定义的类型。
在这里可以直接创建不同类型的ExtensionAbility组件文件
HAP:应用安装的基本单位,一个APP可以包含一个或多个HAP。
包含UIAbility组件或者ExtensionAbility组件的Module可以单独运行。该类型Module运行时会编译生成一个.hap文件
AbilityStage:Module级别的组件容器。
当HAP中的代码首次被加载到进程中时(Module初始化),系统首先会创建一个AbilityStage实例,可以管理Module中的UIAbility组件和ExtensionAbility组件。
AbilityStage与编译期的HAP是一一对应的关系
在开发时,一个项目可能需要包含一个或者多个可以单独运行的Module,对应即为一个Application包含一个或多个AbilityStage。
在运行期,每个AbilityStage持有该Module上定义的UIAbility组件和ExtensionAbility组件。AbilityStage与Module一一对应,即一个Module拥有一个AbilityStage。
当UIAbility组件首次启动时,系统会为UIAbility组件创建实例,并将该实例与持有它的AbilityStage实例相关联。
应用组件与窗口生命周期
-
业务逻辑和UI逻辑分离
-
便于系统对应用组件进行裁剪(无屏设备可裁剪窗口)
-
在多设备(如桌面设备和移动设备)上,应用组件可使用同一套生命周期
在UIAbility的onCreate()的生命周期回调函数中,我们可以在该函数中初始化业务逻辑,例如变量定义,资源预加载等,用于后续的UI展示。
在这张图中,我们可以看到应用组价和窗口的生命周期是松耦合的,这种模式有如下好处:
-
业务逻辑和UI逻辑分离,可以在UIAbility组件中处理与页面无关的业务逻辑。在WindowStage持有的窗口上通过ArkUI处理界面相关的业务逻辑。
-
便于系统对应用组件进行裁剪,例如对于无屏设备,系统在运行应用时不会创建窗口模块,有利于减少系统ROM空间占用。
-
在多设备如桌面设备和移动设备上,应用组件可使用同一套生命周期,应用运行时,系统会自动判断设备,并根据不同设备的窗口形态变换,执行不同的生命周期变化流程。
在不同设备上任务切换场景组件生命周期变化举例。
AbilityStage组件容器
AbilityStage是Module级别的组件容器,HAP的运行期类。
生命周期回调函数:
-
onCreate():AbilityStage实例创建完成之后触发的回调函数。
-
onAcceptWant():指定实例模式的UIAbility组件启动时触发的回调函数。
-
onConfigurationUpdated():系统发生全局配置变化时的回调函数。
-
onMemoryLevel():系统决定调整内存时的回调函数。
如果需要使用AbilityStage的能力,我们需要新建目录和文件,并自定义继承AbilityStage的类。
可以根据需要重写AbilityStage的四个回调函数
export default class MyAbilityStage extends AbilityStage {
onCreate() {
//HAP在首次加载的时候执行,可以在此函数中为该Module做初始化操作。
...
}
onAcceptWant(want:Want) {
//UIAbility组件指定实例启动模式下触发,返回的字符串为UIAbility实例的唯一标识。
...
return 'specifiedUIAbilityInstanceKey';
}
}
定义好类之后,我们需要配置HAP加载入口
// module.json5
{
"module":{
"name":"entry",
"type":"entry",
"srcEntry":"./ets/myabilitystage/MyAbilityStage.ets",
...
}
}
UIAbility组件启动模式
-
单实例启动模式(singleton):该启动模式为默认启动模式,系统运行时,同一UIAbility组件只存在唯一实例。
-
多实例启动模式(multiton):系统每次启动UIAbility组件,都会创建一个新的该类型UIAbility实例。(即在任务视图中可以看到有多个该类型的任务)
-
指定实例启动模式(specified):支持拉起指定key值的UIAbility实例。系统每次拉起指定key值的UIAbility实例,若key值不存在,则创建一个新的实例。
配置如下:
// module.json5
{
"module":{
...
"abilities": {
...
launchType:"singleton"
}
}
}
Want
UIAbility组件间交互载体:Want
Want是对象间信息传递的载体,用于在应用组件之间传递信息
显式Want启动UIAbility组件开发
//调用方页面
// 获取UIAbilityContext
let context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
//创建Want。指定应用包名和Ability名
let want: Want = {
deviceId: '', //指定拉起的应用所在设备,deviceId为空表示本设备
bundleName: 'com.example.myapplication', //指定拉起的应用包名
abilityName: 'FuncAbility', //指定拉起的Ability名
moduleName: 'func', //指定拉起的Ability内的模块名
parameters: { //自定义信息
info: '来自EntryAbility Index页面'
}
}
//根据Want拉起对应Ability,
//调用启动函数,传入Want参数
context.startAbility(want).then(()=>{
//启动成功
}).catch((err: BusinessError)=>{
//启动失败
})
//被调用方UIAbility文件
//接收want,获取调用方信息
export default class FuncAbility extends UIAbility {
...
onCreate(want: Want) {
//接受调用方UIAbility传过来的参数
let info = want.parameters?.info;
...
}
}
隐式Want启动UIAbility组件开发
//设置被调用方的module.json5
{
"module":{
"abilities": [
{
...
"skills": [
{
//设置UIAbility支持的能力类型,如浏览器类型
"entities": [
...
"entity.system.browsable"
],
//设置UIAbility支持的操作,如查看数据
"actions":[
...
"ohos.want.action.viewData"
]
...
}
]
}
]
}
}
//调用方页面
//获取UIAbilityContext
let context:common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
//创建Want,设置action和entities匹配条件。在Want中不指定abilityName字段,而是指定一系列筛选条件
let want:Want = {
action: 'ohos.want.action.viewData',
entities: ['entity.system.browsable'],
url: 'https://www.huawei.com/cn/'
}
//拉起UIAbility
//调用启动函数,传入Want参数
context.startAbility(want).then(()=>{
//启动成功
}).catch((err: BusinessError)=>{
//启动失败
})