【HarmonyOS】Ability Kit - Stage模型_call destroy page in harmony
文章目录
- 一、Ability Kit简介
-
- 1、使用场景
- 2、能力范围
- 二、应用模型
-
- 1、应用模型概况
- 三、stage模型
- 四、总结
一、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 动态共享包。用于提供系统级服务或特定功能服务,通常由系统预装。跟随宿主应用的APP包一起发布,与宿主应用同进程,具有相同的包名和生命周期。
HAP 是应用的 “交付载体”,负责承载完整功能并可独立运行的模块包(应用包)。
- entry:应用的主模块,作为应用的入口。
- feature:应用的动态特性模块,作为应用能力的扩展。
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组件
Ability 是 HarmonyOS 应用的 “最小功能单元”,封装了特定的业务逻辑和生命周期管理。一个应用可以具备多种能力,也就是说可以包含多种 Ability,HarmonyOS 支持以 Ability 为单位进行部署。
作用:
- 处理用户交互(UIAbility)或后台任务(ExtensionAbility)。
- 支持跨设备调用(如在手机和手表间共享能力)。
- 通过 Want 对象实现组件间通信。
核心属性与方法:
- 核心属性
- context:Ability 的上下文,用于访问系统资源(如文件、偏好设置)。
- want:启动 Ability 时携带的意图对象,包含调用者传递的数据。
- 关键方法
- startAbility(want):启动另一个 Ability。
- connectAbility(want, callback):连接到 ExtensionAbility(如服务)。
- terminateSelf():主动销毁当前 Ability。
- UIAbility组件是一种包含UI的应用组件,主要用于和用户交互。例如,在支付应用中,可以将入口功能和收付款功能分别配置为独立的UIAbility。
- UIAbility组件的生命周期只包含创建、销毁、前台、后台等状态,与显示相关的状态通过
WindowStage
的事件暴露给开发者。
- UIAbility组件的生命周期只包含创建、销毁、前台、后台等状态,与显示相关的状态通过
- 对于开发者而言,可以根据具体场景选择单个还是多个UIAbility,划分建议如下:
- 如果开发者希望在任务视图中看到一个任务,建议使用“一个UIAbility+多个页面”的方式。
- 如果开发者希望在任务视图中看到多个任务,或者需要同时开启多个窗口,建议使用多个UIAbility实现不同的功能。
(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 被创建时(如应用启动)。
- 作用:开发者可以在该回调中执行UIAbility整个生命周期中仅发生一次的启动逻辑。初始化资源(如加载布局、绑定数据)。
- onWindowStageCreate()
- 触发时机:当WindowStage实例创建完成后(首次显示 UI)。
- 作用:设置 UI 内容。
- onForeground()
- 触发时机:Ability 首次启动到前台或者从后台转入到前台(用户可见)。
- 作用:恢复 UI 状态。
- onBackground()
- 触发时机:Ability 从前台转入到后台(用户不可见)。
- 作用:保存临时数据,释放资源。
- onDestroy()
- 触发时机:Ability 被销毁时(如应用退出)。
- 作用:开发者可以在该生命周期中执行资源清理、数据保存等相关操作。
- onNewWant()
- 触发时机:当已在前台运行过的UIAbility实例切换至后台后,被再次拉起时(即热启动场景)。
- 作用:开发者可以在该回调中更新要加载的资源和数据等,用于后续的UI展示。
(3)启动模式
- singleton启动模式
singleton启动模式为单实例模式,也是默认情况下的启动模式。
每次调用startAbility()方法时,如果应用进程中该类型的UIAbility实例已经存在,则复用系统中的UIAbility实例。系统中只存在唯一一个该UIAbility实例,即在最近任务列表中只存在一个该类型的UIAbility实例。
- multiton启动模式
multiton启动模式为多实例模式,每次调用startAbility()方法时,都会在应用进程中创建一个新的该类型UIAbility实例。即在最近任务列表中可以看到有多个该类型的UIAbility实例。这种情况下可以将UIAbility配置为multiton(多实例模式)。
- specified启动模式
specified启动模式为指定实例模式,针对一些特殊场景使用(例如文档应用中每次新建文档希望都能新建一个文档实例,重复打开一个已保存的文档希望打开的都是同一个文档实例)。
- 三种启动方式配置
{ \"module\": { // ... \"abilities\": [ { \"launchType\": \"要启动的样式\", // ... } ] }}
(4)基本用法
- 指定UIAbility的启动页面
应用中的UIAbility在启动过程中,需要指定启动页面,否则应用启动后会因为没有默认加载页面而导致白屏。可以在UIAbility的onWindowStageCreate()生命周期回调中,通过WindowStage对象的loadContent()方法设置启动页面。
- 获取UIAbility拉起方的信息
拉起方(UIAbilityA)通过startAbility启动目标方(UIAbilityB)时,UIAbilityB可以通过parameters参数获取UIAbilityA的Pid、BundleName和AbilityName等信息。
5、ExtensionAbility组件
在鸿蒙(HarmonyOS)应用开发中,ExtensionAbility 是一种特殊的组件,用于扩展应用的功能,提供非 UI 核心功能或系统级服务。它是 Ability 的子类,但不直接提供用户界面(UI),而是作为后台服务、扩展点或系统能力的提供者。
(1)概念
-
定位
ExtensionAbility 用于实现应用的扩展功能,如服务卡片等。它不直接与用户交互,而是为其他组件或系统提供特定能力。 -
与 UIAbility 的区别
特性 UIAbility ExtensionAbility 是否提供 UI 必须有用户界面 不直接提供 UI 生命周期 与界面显示 / 隐藏关联 与系统事件或扩展需求关联 典型场景 应用主界面、详情页等 服务卡片等 -
所有类型的ExtensionAbility组件均不能被应用直接启动,而是由相应的系统管理服务拉起,以确保其生命周期受系统管控,使用时拉起,使用完销毁。ExtensionAbility组件的调用方无需关心目标ExtensionAbility组件的生命周期。
(2)常见类型及应用场景
ExtensionAbility 有多种具体类型,每种类型针对特定场景:
- FormExtensionAbility(服务卡片)
- 用途:提供轻量级的信息展示,无需打开应用即可查看或操作。
- 示例:
- 天气应用的卡片显示当前温度。
- 音乐应用的卡片支持播放 / 暂停控制。
- WorkSchedulerExtensionAbility(后台任务调度)
- 用途:在后台执行定时任务、数据同步等操作。
- 示例:
- 新闻应用定时拉取最新内容。
- 健康应用定期同步运动数据。
(3)核心特性
-
独立生命周期
ExtensionAbility 有自己的生命周期回调。import { ExtensionAbility, Want } from \'@ohos.app.ability\';export default class MyExtensionAbility extends ExtensionAbility { onCreate(want: Want): void { // 初始化资源(如创建后台服务) } onDestroy(): void { // 释放资源 }}
-
与其他组件交互
- 通过 Want 对象接收外部请求(如启动服务、传递参数)。
- 与 UIAbility 配合:例如,服务卡片点击后跳转到对应的 UIAbility 页面。
- 系统级集成
- 注册为系统服务:例如,输入法需在系统中注册才能被调用。
- 响应系统事件:如后台任务调度需监听系统资源状态。
(4)配置文件
{ \"module\": { \"name\": \"feature_form\", \"type\": \"feature\",// 模块类型(entry/feature) \"reqPermissions\": [], \"extensionAbilities\": [ { \"name\": \"com.example.FormExtensionAbility\", // ExtensionAbility 类名 \"srcEntry\": \"./ets/extension/FormExtensionAbility.ts\", \"description\": \"$string:form_ext_desc\", \"icon\": \"$media:form_icon\", \"label\": \"$string:form_label\", \"type\": \"form\", // 类型为服务卡片 } ] }}
6、AbilityStage组件容器
(1)概念
AbilityStage是一个Module级别的组件容器,应用的HAP在首次加载时会创建一个AbilityStage实例,可以对该Module进行初始化等操作。AbilityStage与Module一一对应,即一个Module拥有一个AbilityStage。
AbilityStage拥有onCreate()、onDestroy()等生命周期回调。
onCreate(): void
在加载Module的第一个Ability实例前,系统会先创建对应的AbilityStage实例,并在AbilityStage创建完成后,自动触发该回调。开发者可以在该回调中执行Module的初始化操作。
onAcceptWant(want: Want): string
当启动模式配置为specified的UIAbility被拉起时,会触发该回调,并返回一个string作为待启动的UIAbility实例的唯一标识。如果系统中已经有相同标识的UIAbility实例存在,则复用已有实例,否则创建新的实例。
onDestroy(): void
在对应Module的最后一个Ability实例退出后会触发该回调。此方法将在正常的调度生命周期中调用,当应用程序异常退出或被终止时,将不会调用此方法。
(2)创建
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\", // ... }}
(3)举例
- 用户首次打开 音乐App
- AbilityStage 创建
AbilityStage.onCreate() → 初始化全局资源
- UIAbility 创建(主界面)
MainAbility.onCreate() → 初始化播放列表数据MainAbility.onWindowStageCreate() → 加载主界面布局MainAbility.onForeground() → 界面显示,开始播放音乐
- 用户按 Home 键切到后台
- UIAbility 进入后台
MainAbility.onBackground() → 暂停UI更新,但音乐继续播放
- 用户锁屏后
- ExtensionAbility(音乐服务)继续运行
MusicService(ExtensionAbility)保持运行 → 持续播放音乐
- 用户关闭 App
- UIAbility 销毁
MainAbility.onDestroy() → 释放界面资源
- ExtensionAbility 停止
MusicService.onDisconnect() → 断开与UI的连接MusicService.onStop() → 停止音乐播放,释放资源
- AbilityStage 销毁
AbilityStage.onDestroy() → 关闭全局资源
(4)时序图
7、应用上下文Context
(1)概念
Context是应用中对象的上下文,其提供了应用的一些基础信息,它提供了应用运行时的环境信息和资源访问能力,让组件(如 Ability)能够与系统交互。
- Context 的核心作用
- 访问应用资源(如文件、字符串、图片)。
- 启动其他 Ability(通过
startAbility
方法)。 - 获取系统服务(如通知、网络、位置)。
- 管理应用数据(如偏好设置、数据库)。
- 获取应用信息(如包名、版本号)。
(2)使用场景
- 获取基本信息
- 获取应用文件路径
- 监听UIAbility生命周期变化
8、Want概述
Want 对象 —— 组件间通信的 “信使”,是一种对象,用于在应用组件之间传递信息。其中,一种常见的使用场景是作为startAbility()方法的参数。例如,当UIAbilityA需要启动UIAbilityB并向UIAbilityB传递一些数据时,可以使用Want作为一个载体,将数据传递给UIAbilityB。
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!\'}};// 启动Abilitythis.context.startAbility({ want });
(1)用途
是对象间信息传递的载体,可以用于应用组件间的信息传递。
- 作为
startAbility
的参数
例如,当UIAbilityA需要启动UIAbilityB并向UIAbilityB传递一些数据时,可以使用Want作为一个载体,将数据传递给UIAbilityB。
(2)类型
显示
-
在启动时指定
abilityName, bundleName
的 Want 。 -
显式Want通常用于应用内组件启动,通过在Want对象内指定本应用Bundle名称信息bundleName和abilityName来启动应用内目标组件。
-
当有明确处理请求的对象时,显式Want是一种简单有效的启动目标应用组件的方式。
import { Want } from \'@kit.AbilityKit\';let wantInfo: Want = { deviceId: \'\', // deviceId为空表示本设备 bundleName: \'com.example.myapplication\', abilityName: \'FuncAbility\',}
隐式
-
在启动时未指定
abilityName
的 Want 。 -
当需要处理的对象不明确时,可以使用隐式Want,在当前应用中使用其他应用提供的某个能力,而不关心提供该能力的具体应用。隐式Want使用skills标签来定义需要使用的能力,并由系统匹配声明支持该请求的所有应用来处理请求。
-
例如,需要打开一个链接的请求,系统将匹配所有声明支持该请求的应用,然后让用户选择使用哪个应用打开链接。
import { Want } from \'@kit.AbilityKit\';let wantInfo: Want = { // 如果希望仅在特定的应用包中隐式查询,取消下面一行的注释。 // bundleName: \'com.example.myapplication\', action: \'ohos.want.action.search\', // 可以省略实体(entities) entities: [ \'entity.system.browsable\' ], uri: \'https://www.test.com:8080/query/student\', type: \'text/plain\',};
- 根据系统中待匹配应用组件的匹配情况不同,使用隐式Want启动应用组件时会出现以下三种情况。
- 未匹配到满足条件的应用组件:启动失败。
- 匹配到一个满足条件的应用组件:直接启动该应用组件。
- 匹配到多个满足条件的应用组件(UIAbility):弹出选择框让用户选择。