- Ability Kit(程序框架服务)提供了应用程序开发和运行的应用模型,是系统为开发者提供的应用程序所需能力的抽象提炼,它提供了应用程序必备的组件和运行机制。
应用模型
- 随着系统的演进发展,先后提供了两种应用模型:
- FA(Feature Ability)模型:从API 7开始支持的模型,已经不再主推。
- Stage模型:从API 9开始新增的模型,是目前主推且会长期演进的模型。在该模型中,由于提供了AbilityStage、WindowStage等类作为应用组件和Window窗口的“舞台”,因此称这种应用模型为Stage模型。
- Stage模型概念图:
- Stage模型有三类进程:1. 主进程 2. ExtensionAbility进程 3. 渲染进程
- AbilityStage: 每个Entry类型或者Feature类型的HAP在运行期都有一个AbilityStage类实例。
- UIAbility组件:是一种包含UI的应用组件,主要用于和用户交互。
- ExtensionAbility组件:是一种面向特定场景的应用组件。开发者并不直接从ExtensionAbility组件派生,而是需要使用ExtensionAbility组件的派生类。
- WindowStage:每个UIAbility实例都会与一个WindowStage类实例绑定,该类起到了应用进程内窗口管理器的作用。
- Context:在Stage模型上,Context及其派生类向开发者提供在运行期可以调用的各种资源和能力。
UIAbility组件概述
UIAbility是HarmonyOS应用框架的核心组件,负责管理用户界面与系统资源的交互。其核心设计理念包括:
- 跨端迁移:支持应用组件在不同设备间无缝迁移
- 多端协同:实现多窗口、多任务并行处理
- 窗口管理:每个UIAbility实例对应一个独立任务窗口, 支持单实例/多实例运行模式
- 生命周期感知:提供完整的生命周期回调体系
- 多模块交互:支持与Service/ExtensionAbility深度协作
- 状态可移植:通过统一的上下文管理机制(UIAbilityContext)实现运行状态的持久化存储与恢复
- 原子化调度:系统调度的最小单位,支持独立部署与运行
- UI容器属性:通过WindowStage管理ArkUI页面栈
声明配置示例(module.json5):
{
"module": {
"abilities": [
{
"name": "EntryAbility", // UIAbility组件的名称
"launchType": "singleton", //启动模式
"srcEntry": "./ets/entryability/EntryAbility.ets", // UIAbility组件的代码路径
"description": "$string:EntryAbility_desc",// UIAbility组件的描述信息
"icon": "$media:layered_image",// UIAbility组件的图标
"label": "$string:EntryAbility_label", // UIAbility组件的标签
"startWindowIcon": "$media:startIcon", // UIAbility组件启动页面图标资源文件的索引
"startWindowBackground": "$color:start_window_background",// UIAbility组件启动页面背景颜色资源文件的索引
"exported": true,
}
]
}
}
生命周期管理
生命周期状态机包含6种状态:Create → WindowStageCreate → Foreground → Background → WindowStageDestroy → Destroy
创建阶段
export default class MainAbility extends UIAbility {
onCreate(want: Want, launchParam: LaunchParam) {
console.log("Ability创建");
// 初始化全局资源
this.globalData = { count: 0 };
}
}
窗口阶段
onWindowStageCreate(windowStage: WindowStage) {
console.log("窗口创建完成");
// 加载主页面
windowStage.loadContent('pages/Index', (err) => {
if (err) console.error('加载失败:', err);
});
// 监听窗口事件
windowStage.on('windowStageEvent', (event) => {
switch(event) {
case WindowStageEventType.SHOWN:
this.handleWindowFocus();
break;
case 'ACTIVE':
console.log('窗口获取焦点');
break;
case 'INACTIVE':
console.log('窗口失去焦点');
break;
}
});
}
onWindowStageWillDestroy(windowStage: window.WindowStage) {
// 释放通过windowStage对象获取的资源
}
onWindowStageDestroy(): void {
// 释放UI资源
// 例如在onWindowStageDestroy()中注销获焦/失焦等WindowStage事件
}
前后台切换
onForeground() {
console.log("进入前台");
// 申请定位权限等前台资源
requestLocationPermission();
}
onBackground() {
// 释放内存资源
this.globalData = null;
}
销毁阶段
onDestroy() {
console.log("Ability销毁");
// 清理残留资源
if (this.timer) {
clearInterval(this.timer);
}
}
启动模式
模式 | 特性 | 使用场景 |
---|---|---|
singleton | 默认,单实例, | 主界面/全局服务 |
multiton | 多实例,独立运行 | 并行任务处理 |
specified | 指定Key标识实例 | 文档编辑器等场景 |
1. singleton启动模式:
- 单实例模式(默认),共享同一上下文。
- 每次调用startAbility()方法时,如果应用进程中该类型的UIAbility实例已经存在,则复用系统中的UIAbility实例。
- 系统中只存在唯一一个该UIAbility实例,即在最近任务列表中只存在一个该类型的UIAbility实例。(进入该UIAbility的onNewWant()回调)
- 当应用的UIAbility实例已创建,且UIAbility配置为singleton启动模式时,再次调用startAbility()方法启动该UIAbility实例时,只会进入该UIAbility的onNewWant()回调,不会进入其onCreate()和onWindowStageCreate()生命周期回调。应用可以在该回调中更新要加载的资源和数据等,用于后续的UI展示。
2. multiton启动模式:
- 多实例模式。
- 每次调用startAbility()方法时,都会在应用进程中创建一个新的该类型UIAbility实例。即在最近任务列表中可以看到有多个该类型的UIAbility实例。
3. specified启动模式:
- 指定实例模式,针对一些特殊场景使用(例如文档应用中每次新建文档希望都能新建一个文档实例,重复打开一个已保存的文档希望打开的都是同一个文档实例)。
- 在创建UIAbility实例之前,开发者可以为该实例指定一个唯一的字符串Key,这样在调用startAbility()方法时,应用就可以根据指定的Key来识别响应请求的UIAbility实例。在EntryAbility中,调用startAbility()方法时,可以在want参数中增加一个自定义参数,例如instanceKey,以此来区分不同的UIAbility实例。
// AbilityStage实现
export default class MyAbilityStage extends AbilityStage {
onAcceptWant(want: Want): string {
return `SPEC_KEY_${want.parameters.docId}`;
}
}
// 启动时指定Key
let want = {
abilityName: 'SpecifiedAbility',
parameters: { docId: 'DOC_2023' }
};
数据同步机制
EventHub事件总线
// 发布事件
this.context.eventHub.emit('userUpdated', { id: 1, name: 'Alice' });
// 订阅事件
this.context.eventHub.on('userUpdated', (user) => {
console.log('用户信息更新:', user);
});
应用级存储
// 全局存储(跨Ability)
AppStorage.set('userInfo', { token: 'abc123' });
// 局部存储(当前Ability)
LocalStorage.set('settings', { theme: 'dark' });
跨Ability交互
参数传递
// 启动时传递参数
let want = {
abilityName: 'DetailAbility',
parameters: { id: 123, type: 'video' }
};
// 接收参数
export default class DetailAbility extends UIAbility {
onCreate(want: Want) {
let params = want.parameters;
console.log('接收参数:', params.id, params.type);
}
}
结果回调
// 发起请求
startAbilityForResult(want).then((result) => {
console.log('返回数据:', result.data);
});
// 返回结果
terminateSelfWithResult({
resultCode: 200,
want: {
parameters: { success: true }
}
});
实战技巧
启动UIAbility的指定页面
- 一个UIAbility可以对应多个页面,在不同的场景下启动该UIAbility时需要展示不同的页面。
- UIAbility的启动分为两种情况:UIAbility冷启动和UIAbility热启动。
- UIAbility冷启动:指的是UIAbility实例处于完全关闭状态下被启动,这需要完整地加载和初始化UIAbility实例的代码、资源等。
- UIAbility热启动:指的是UIAbility实例已经启动并在前台运行过,由于某些原因切换到后台,再次启动该UIAbility实例,这种情况下可以快速恢复UIAbility实例的状态。
- 调用方UIAbility指定启动页面:通过want中的parameters参数增加一个自定义参数传递页面跳转信息。
// 冷启动指定页面
if (this.isColdStart) {
windowStage.loadContent('pages/Login');
} else {
router.pushUrl({ url: 'pages/Dashboard' });
}
// 热启动页面跳转
this.router.replaceUrl({ url: 'pages/Profile' });
错误处理
try {
await this.context.startAbility(want);
} catch (err) {
if (err.code === 1008500011) {
showToast('文件传输权限不足');
} else {
console.error('启动失败:', err);
}
}
- 通过掌握UIAbility的生命周期管理、启动模式配置、数据同步机制及跨组件交互技巧,开发者可以构建高效、灵活的HarmonyOS应用架构,实现真正的分布式能力。