文章目录
一、Ability Kit简介
Ability Kit(程序框架服务)提供了应用程序开发和运行的应用模型,是系统为开发者提供的应用程序所需能力的抽象提炼,它提供了应用程序必备的组件和运行机制。
1、使用场景
- 应用的多Module开发:应用可通过不同类型的 Module(HAP、HAR、HSP)来实现应用的功能开发。其中,HAP 用于实现应用的功能和特性,HAR 与 HSP 用于实现代码和资源的共享。
格式 全称 描述 HAP HarmonyOS Ability Package 鸿蒙应用的基础部署单元,包含一个或多个 Ability 及其资源,可独立安装。 HAR HarmonyOS Archive 静态共享包。鸿蒙应用的组件化模块,用于代码复用和模块化开发,不可独立安装。 HSP HarmonyOS Service Package 动态共享包。用于提供系统级服务或特定功能服务,通常由系统预装。
- HAP 是应用的 “交付载体”,负责承载完整功能并可独立运行。
- HAR 是应用的 “积木”,用于模块化开发和代码复用。
- HSP 是系统的 “基础设施”,为应用提供底层服务支持。
- 应用内的交互:应用内的不同模块或组件之间可以相互跳转。比如,在微信应用中,通过入口 UIAbility 组件启动其他 UIAbility 组件。
如图所示,在 entry
模块下的 entryAbility
和 entryAbilityTwo
是应用内同模块拉起,而在 entry
模块下的 entryAbility
和 TestMoudle
模块下的 entryAbility
是应用内跨模块拉起,可以实现相互跳转。
2、能力范围
- 提供应用进程创建和销毁、应用生命周期调度能力。
- 提供应用组件运行入口、应用组件生命周期调度、组件间交互等能力。
- 提供应用上下文环境、系统环境变化监听等能力。
- 提供应用流转能力。
二、应用模型
应用模型是系统为开发者提供的应用程序所需能力的抽象提炼,它提供了应用程序必备的组件和运行机制。有了应用模型,开发者可以基于一套统一的模型进行应用开发,使应用开发更简单、高效。
1、应用模型概况
随着系统的演进发展,先后提供了两种应用模型:
- FA(Feature Ability)模型:从API 7开始支持的模型,已经不再主推。
- Stage模型:从API 9开始新增的模型,是目前主推且会长期演进的模型。在该模型中,由于提供了AbilityStage、WindowStage等类作为应用组件和Window窗口的“舞台”,因此称这种应用模型为Stage模型。
三、stage模型
1、图片概述
(1)核心概念
- 运行时概念:应用在设备上运行时的组件结构。
- 编译期概念:应用开发和打包时的模块结构。
- Context:上下文基类,提供组件运行所需的环境信息。
- Ability:应用的核心组件,负责提供 UI 或服务。
(2)运行时
Context 继承关系
基类:
Context
是所有上下文的基类。子类:
UIAbilityContext
:UI 相关能力的上下文。
UIAbility 相关组件
UIAbility:提供 UI 界面的核心组件,对应应用的一个页面或功能模块。
Window:UI 界面的窗口容器。
WindowStage:管理 Window 的生命周期和事件。
ArkUI Page:基于 ArkUI 框架的 UI 页面。
AbilityStage
管理一组相关的 Ability,是应用内的功能模块容器。
每个 AbilityStage 对应应用的一个功能模块。
(3)编译期
HAP
应用的部署单元,包含一个或多个 Ability。
对应运行时的
UIAbility
或ExtensionAbility
。
Bundle
- 应用的安装包,包含一个或多个 HAP。
2、目录概览
(1)app.json5配置文件
{
"app": {
"bundleName": "com.example.mysecond", //包名
"vendor": "example",
"versionCode": 1000000,
"versionName": "1.0.0", // 版本号
"icon": "$media:layered_image",
// 在AppScope的media下配置图标,会在设置里改变图标,但在界面不会改变
"label": "$string:app_name"
// 在AppScope的media下配置名字,会在设置里改变名字,但在界面不会改变
}
}
(2)module.json5配置文件
"abilities": [
{
"name": "EntryAbility",
"srcEntry": "./ets/entryability/EntryAbility.ets",
"description": "$string:EntryAbility_desc",
"icon": "$media:layered_image", // 图标
"label": "$string:EntryAbility_label", // 名字
"startWindowIcon": "$media:startIcon",
"startWindowBackground": "$color:start_window_background",
"exported": true,
"skills": [
{
"entities": [
"entity.system.home"
],
"actions": [
"action.system.home"
]
}
]
}
]
3、构成要素
应用结构
Entry.hap:应用的主模块,包含核心 UI 能力。
Feature1.hap:功能模块,包含卡片能力。
Feature2.hsp:服务模块,包含页面能力。
app.json5:应用全局配置文件。
4、UIAbility组件
UIAbility组件是一种包含UI的应用组件,主要用于和用户交互,以及相关的生命周期和资源管理 。
(1)声明配置
{
"module": {
// ...
"abilities": [
{
"name": "EntryAbility", // UIAbility组件的名称
"srcEntry": "./ets/entryability/EntryAbility.ets", // UIAbility组件的代码路径
"description": "$string:EntryAbility_desc", // UIAbility组件的描述信息
"icon": "$media:icon", // UIAbility组件的图标
"label": "$string:EntryAbility_label", // UIAbility组件的标签
"startWindowIcon": "$media:icon", // UIAbility组件启动页面图标资源文件的索引
"startWindowBackground": "$color:start_window_background", // UIAbility组件启动页面背景颜色资源文件的索引
// ...
}
]
}
}
(2)生命周期
export default class EntryAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate');
}
onDestroy(): void {
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy');
}
onWindowStageCreate(windowStage: window.WindowStage): void {
// Main window is created, set main page for this ability
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
windowStage.loadContent('pages/Index', (err) => {
if (err.code) {
hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err));
return;
}
hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.');
});
}
onWindowStageDestroy(): void {
// Main window is destroyed, release UI related resources
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
}
onForeground(): void {
// Ability has brought to foreground
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground');
}
onBackground(): void {
// Ability has back to background
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground');
}
}
- onCreate()
- 触发时机:Ability 被创建时(如应用启动)。
- 作用:初始化资源(如加载布局、绑定数据)。
- onWindowStageCreate()
- 触发时机:界面窗口创建时(首次显示 UI)。
- 作用:设置 UI 内容(如加载页面布局)。
- onForeground()
- 触发时机:Ability 进入前台(用户可见)。
- 作用:恢复 UI 状态(如重新加载数据)。
- onBackground()
- 触发时机:Ability 进入后台(用户不可见)。
- 作用:保存临时数据,释放资源(如暂停动画)。
- onDestroy()
- 触发时机:Ability 被销毁时(如应用退出)。
- 作用:释放所有资源(如关闭网络连接)。
(3)启动模式
- singleton启动模式
singleton启动模式为单实例模式,也是默认情况下的启动模式。
每次调用startAbility()方法时,如果应用进程中该类型的UIAbility实例已经存在,则复用系统中的UIAbility实例。系统中只存在唯一一个该UIAbility实例,即在最近任务列表中只存在一个该类型的UIAbility实例。
- multiton启动模式
multiton启动模式为多实例模式,每次调用startAbility()方法时,都会在应用进程中创建一个新的该类型UIAbility实例。即在最近任务列表中可以看到有多个该类型的UIAbility实例。这种情况下可以将UIAbility配置为multiton(多实例模式)。
- specified启动模式
specified启动模式为指定实例模式,针对一些特殊场景使用(例如文档应用中每次新建文档希望都能新建一个文档实例,重复打开一个已保存的文档希望打开的都是同一个文档实例)。
(4)基本用法
- 指定UIAbility的启动页面
应用中的UIAbility在启动过程中,需要指定启动页面,否则应用启动后会因为没有默认加载页面而导致白屏。可以在UIAbility的onWindowStageCreate()生命周期回调中,通过WindowStage对象的loadContent()方法设置启动页面。
- 获取UIAbility拉起方的信息
拉起方(UIAbilityA)通过startAbility启动目标方(UIAbilityB)时,UIAbilityB可以通过parameters参数获取UIAbilityA的Pid、BundleName和AbilityName等信息。
5、AbilityStage组件容器
AbilityStage是一个Module级别的组件容器,应用的HAP在首次加载时会创建一个AbilityStage实例,可以对该Module进行初始化等操作。AbilityStage与Module一一对应,即一个Module拥有一个AbilityStage。
AbilityStage拥有onCreate()、onDestroy()生命周期回调。
DevEco Studio默认工程中未自动生成AbilityStage,如需要使用AbilityStage的能力,可以手动新建一个AbilityStage文件。
- 在工程Module对应的ets目录下,新建一个目录并命名为myabilitystage。
- 在myabilitystage目录,新建一个文件并命名为MyAbilityStage.ets。
- 打开MyAbilityStage.ets文件,导入AbilityStage的依赖包,自定义类继承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';
}
}
在module.json5配置文件中,通过配置 srcEntry 参数来指定模块对应的代码路径,以作为HAP加载的入口。
{
"module": {
"name": "entry",
"type": "entry",
"srcEntry": "./ets/myabilitystage/MyAbilityStage.ets",
// ...
}
}
6、Want概述
Want 对象 —— 组件间通信的 “信使”
定义:Want
是 HarmonyOS 中用于请求启动 Ability 或进行组件间数据传递的 “意图对象”。 类比:就像 “快递包裹”,里面装着 “收件地址”(目标 Ability)和 “物品”(传递的数据)。
核心属性:
bundleName
:目标应用的包名(如com.example.calculator
)。abilityName
:目标 Ability 的类名(如com.example.calculator.MainAbility
)。parameters
:携带的数据(如{ "key": "value" }
)。
常见用法:
// 创建一个Want,启动另一个Abilityconst
want = {
bundleName: 'com.example.targetapp',
abilityName: 'com.example.targetapp.SecondAbility',
parameters: {
message: 'Hello from MainAbility!'}};// 启动Ability
context.startAbility({ want });
用途
是对象间信息传递的载体,可以用于应用组件间的信息传递
- 作为
startAbility
的参数
例如,当UIAbilityA需要启动UIAbilityB并向UIAbilityB传递一些数据时,可以使用Want作为一个载体,将数据传递给UIAbilityB。
类型
(1)显示
在启动时指定 abilityName, bundleName
的 Want 。
import Want from '@ohos.app.ability.Want';
import { common } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
@Entry
@Component
struct Index {
@State message: string = 'Hello World';
// 3.获取上下文对象
context = getContext(this) as common.UIAbilityContext
build() {
Column() {
Column() {
Button('买菜')
.onClick(() => {
// 1.准备 want(参数信息)
let wantInfo: Want = {
deviceId: '', // 空表示本设备
bundleName: 'com.example.mysecond', // AppScore/app.json5
moduleName: 'entry', // 模块名
abilityName: 'EntryAbilityTwo', // src/main/ets/module.json5
parameters: {
info: '来自entryAbility'
}
}
// 2.利用 context startAbility 调起 UIAbility
// 返回一个 Promise 对象
this.context.startAbility(wantInfo)
.then(() => {
console.log('success')
})
.catch((error: BusinessError) => {
console.log('fail ', error)
})
})
}
}
}
}
(2)隐式
在启动时未指定 abilityName
的 Want 。
Button('Ability - 跨模块')
.onClick(() => {
// 1.准备 want(参数信息)
let wantInfo: Want = {
deviceId: '', // 空表示本设备
bundleName: 'com.example.mysecond', // AppScore/app.json5
moduleName: 'TestMoudle', // 模块名 !!
abilityName: 'TestMoudleAbility', // src/main/ets/module.json5 !!
parameters: {
info: '来自entryAbility'
}
}
// 2.利用 context startAbility 调起 UIAbility
// 返回一个 Promise 对象
this.context.startAbility(wantInfo)
.then(() => {
console.log('success')
})
.catch((error: BusinessError) => {
console.log('fail ', error)
})