一、基本概念
多个应用组件共享同一个ArkTS引擎(运行ArkTS语言的虚拟机)实例,应用组件之间可以方便的共享对象和状态,同时减少复杂应用运行对内存的占用。
-
AbilityStage:每个Entry类型或者Feature类型的HAP在运行期都有一个AbilityStage类实例,当HAP中的代码首次被加载到进程中的时候,系统会先创建AbilityStage实例。
-
UIAbility组件和ExtensionAbility组件:UIAbility组件是一种包含UI的应用组件,主要用于和用户交互。ExtensionAbility组件是一种面向特定场景的应用组件,开发者直接使用ExtensionAbility组件的派生类。
-
WindowStage:每个UIAbility实例都会与一个WindowStage类实例绑定,该类起到了应用进程内窗口管理器的作用。也就是说UIAbility通过WindowStage持有了一个主窗口,该主窗口为ArkUI提供了绘制区域。
-
Context:在Stage模型上,Context及其派生类向开发者提供在运行期可以调用的各种资源和能力。UIAbility组件和各种ExtensionAbility派生类都有各自不同的Context类。
二、UIAbility组件
1、基本概念
- UIAbility组件是一种包含UI的应用组件,主要用于和用户交互。是系统调度的基本单元,为应用提供绘制界面的窗口。一个应用可以包含一个或多个UIAbility组件。
- 每一个UIAbility组件实例都会在最近任务列表中显示一个对应的任务
- UIAbility的生命周期包含创建/销毁/前台/后台等状态,与显示相关的状态通过WindowStage的事件暴露给开发者。
选择单个还是多个UIAbility:
如果希望在任务视图中看到一个任务,则建议使用一个UIAbility,多个页面的方式。
2、生命周期
- onCreate:UIAbility实例创建,可以在onCreate回调中进行相关初始化操作。
- onForeground:在UIAbility的UI可见之前,如UIAbility切换至前台时触发。
- onBackground:在UIAbility的UI完全不可见之后,如UIAbility切换至后台时候触发。可以在该回调中释放UI不可见时无用的资源,或者在此回调中执行较为耗时的操作,例如状态保存等。
- onDestroy:在UIAbility销毁时触发。可以在onDestroy回调中进行系统资源的释放、数据的保存等操作。
export default class EntryAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
}
onWindowStageCreate(windowStage: window.WindowStage): void {
}
onForeground(): void {
}
onBackground(): void {
}
onWindowStageDestroy(): void {
}
onDestroy(): void {
}
}
onNewWant
-
当应用的UIAbility实例已创建,且UIAbility配置为singleton启动模式时(默认启动模式),再次调用startAbility()方法启动该UIAbility实例时,只会进入该UIAbility的onNewWant()回调。
-
比如通过deeplink或appLink的方式再次启动应用,也会进入onNewWant()回调。
3、启动模式
-
singleton启动模式为单实例模式,也是默认情况下的启动模式。每次调用startAbility()方法时,如果应用进程中该类型的UIAbility实例已经存在,则复用系统中的UIAbility实例,只会进入该UIAbility的onNewWant()回调。最近任务列表中只存在一个该类型的UIAbility实例。
-
multiton启动模式为多实例模式,每次调用startAbility()方法时,都会在应用进程中创建一个新的该类型UIAbility实例。
-
specified启动模式为指定实例模式,针对一些特殊场景使用通过key匹配对应的UIAbility,如匹配成功则启动该UIAbility实例,如果实现则创建新的UIAbility实例。
实例模式的使用:
-
调用startAbility()方法时,可以在want参数中增加一个自定义参数,例如instanceKey,以此来区分不同的UIAbility实例。
-
在Ability启动之前,会先进入对应的AbilityStage的onAcceptWant()生命周期回调中,以获取该UIAbility实例的Key值。然后系统会自动匹配,如果存在与该UIAbility实例匹配的Key,则会启动与之绑定的UIAbility实例,否则会创建一个新的UIAbility实例。
4、UIAbility使用
4.1 启动UIAbility
@Entry
@Component
struct Index {
private context = getContext(this) as common.UIAbilityContext;
startAbilityTest() {
let want: Want = {
deviceId: '', // deviceId为空表示本设备
bundleName: 'com.example.myapplication',
moduleName: 'func', // moduleName非必选
abilityName: 'FuncAbility',
parameters: { // 自定义信息
info: '来自EntryAbility Index页面',
},
}
this.context.startAbility(want);
}
}
启动UIAbility有显式Want启动和隐式Want启动两种方式。
-
显式Want启动:在want参数中需要设置该应用bundleName和abilityName
-
隐式Want启动:根据匹配条件由用户选择启动哪一个UIAbility,其入参want中指定了一系列的entities和actions字段
4.2 参数接收
在onCreate()或者onNewWant()回调中接收前一个UIAbility传递过来的参数
export default class FuncAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
// 接收调用方UIAbility传过来的参数
let funcAbilityWant = want;
let info = funcAbilityWant?.parameters?.info;
// ...
}
}
4.3 启动UIAbility并获取返回结果
// 启动并接收返回的参数
let want :Want = {
}
this.context.startAbilityForResult(want).then((data) => {
// ...
}).catch((err: BusinessError) => {
})
let abilityResult : common.AbilityResult = {
resultCode: 1,
want : {
}
}
//停止自身并返回所需参数
this.context.terminateSelfWithResult(abilityResult, (err) => {
if (err.code) {
console.error(`Failed to terminate self with result. Code is ${err.code}, message is ${err.message}`);
return;
}
})
4.4 停止当前UIAbility
this.context.terminateSelf((error) => {
})
4.5 关闭所有UIAbility
this.context.getApplicationContext().killAllProcesses()
5、UIAbility和UI组件通信
-
使用EventHub进行数据通信,通过发布订阅方式来实现事件的传递。
-
使用AppStorage/LocalStorage进行数据同步,通过这两种应用级别的状态管理方案通信。
5.1 EventHub事件发送
@Entry
@Component
struct Index {
private context = getContext(this) as common.UIAbilityContext;
// 页面展示
build() {
Button('按钮')
.onClick(() => {
// 不带参数触发自定义“event1”事件
this.context.eventHub.emit('event1');
// 带多个参数触发自定义“event1”事件
this.context.eventHub.emit('event1', 2, 'test');
})
Button('关闭')
.onClick(() => {
//取消该事件的订阅
this.context.eventHub.off('event1');
})
}
}
5.2 EventHub事件接收
export default class EntryAbility extends UIAbility {
eventFunc() {
console.log('EntryAbility', "eventFunc:");
}
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
let eventHub = this.context.eventHub;
// 执行订阅操作
eventHub.on('event1', this.eventFunc)
eventHub.on('event1', (data: String, data1: number) => {
//接收事件
console.log('EntryAbility', "data:" + data + "====" + data1);
})
}
}
三、ExtensionAbility组件
-
ExtensionAbility组件是基于特定场景(例如服务卡片、输入法等)提供的应用组件,只能使用系统已定义的类型。
-
所有类型的ExtensionAbility组件均不能被应用直接启动,而是由相应的系统管理服务拉起,以确保其生命周期受系统管控,使用时拉起,使用完销毁。
1、常用ExtensionAbility
-
FormExtensionAbility: FORM类型的ExtensionAbility组件,用于提供服务卡片的相关能力。
-
WorkSchedulerExtensionAbility:WORK_SCHEDULER类型的ExtensionAbility组件,用于提供延迟任务的相关能力。
-
InputMethodExtensionAbility:INPUT_METHOD类型的ExtensionAbility组件,用于实现输入法应用的开发。
-
BackupExtensionAbility:BACKUP类型的ExtensionAbility组件,用于提供备份及恢复应用数据的能力
-
DriverExtensionAbility:DRIVER类型的ExtensionAbility组件,用于提供驱动相关扩展框架
-
EmbeddedUIExtensionAbility:EMBEDDED_UI类型的ExtensionAbility组件,用于提供跨进程界面嵌入的能力。
-
ShareExtensionAbility:SHARE类型的ExtensionAbility组件,用于提供分享模板服务扩展的能力。