Stage应用模型是HarmonyOS应用开发的核心架构,理解Stage模型是掌握鸿蒙开发的关键。本文将深入讲解Stage模型的架构设计、UIAbility组件的完整生命周期、Ability间的通信机制、进程与线程模型、以及应用配置文件等核心内容。通过本文的学习,希望开发者能够熟练创建和管理UIAbility组件,掌握Ability之间的数据传递和跳转方法,理解应用进程和线程的管理机制,最终能够独立开发出结构清晰、功能完整的HarmonyOS应用。
一、Stage模型概述
1.1 应用模型的演进
HarmonyOS先后提供了两种应用模型。FA模型是从API 7开始支持的模型,已经不再主推。Stage模型是从API 9开始新增的模型,是目前主推且会长期演进的模型。
Stage模型的命名来源于其核心设计:AbilityStage和WindowStage作为应用组件和窗口的舞台,所有UI组件在此舞台上呈现。这种设计理念体现了HarmonyOS对应用组件的抽象和管理方式。
FA模型与Stage模型的主要区别体现在以下几个方面。
在组件类型上,FA模型提供PageAbility、ServiceAbility、DataAbility、FormAbility四种类型的Ability,而Stage模型提供UIAbility和ExtensionAbility两种类型。UIAbility负责UI界面展示,ExtensionAbility负责特定场景的扩展能力。
在生命周期管理上,FA模型的PageAbility生命周期包含onStart、onActive、onInactive、onBackground、onStop等回调,而Stage模型的UIAbility生命周期包含onCreate、onForeground、onBackground、onDestroy等核心回调,生命周期管理更加清晰和规范。
在开发范式上,FA模型支持Java和JS/TS两种开发语言,而Stage模型主要使用ArkTS,结合ArkUI声明式UI框架,提供更加现代化的开发体验。
1.2 Stage模型的核心概念
Stage模型包含以下几个核心概念。
AbilityStage是每个Entry或Feature类型HAP在运行期的类实例。当HAP中的代码首次被加载到进程中时,系统会先创建AbilityStage实例。AbilityStage负责管理该HAP中的所有Ability组件,提供了组件创建、生命周期管理、环境初始化等能力。
UIAbility是一种包含UI的应用组件,主要用于和用户交互。每个UIAbility组件实例对应一个最近任务列表中的任务。UIAbility的生命周期只包含创建、销毁、前台、后台等状态,与显示相关的状态通过WindowStage的事件暴露给开发者。
WindowStage是UIAbility实例绑定的窗口管理器,起到了应用进程内窗口管理器的作用。它包含一个主窗口,为ArkUI提供了绘制区域。WindowStage的生命周期与UIAbility紧密关联,在UIAbility创建后、进入前台之前,系统会创建WindowStage实例并触发onWindowStageCreate回调。
Context及其派生类向开发者提供在运行期可以调用的各种资源和能力。UIAbility组件和各种ExtensionAbility组件的派生类都有各自不同的Context类,它们都继承自基类Context,各自根据所属组件提供不同的能力。
1.3 Stage模型的架构优势
Stage模型相比FA模型具有以下架构优势。
组件化设计更加清晰。应用由多个UIAbility组件构成,每个UIAbility组件独立运行,独立管理生命周期。这种设计使得复杂应用能够将不同功能模块独立管理,提高代码的可维护性和运行时的独立性。
窗口管理更加规范。每个UIAbility组件拥有独立的WindowStage,负责管理应用窗口的创建、显示和销毁。窗口的创建和销毁由系统统一管理,与UIAbility的生命周期同步。
面向对象的开发方式更加友好。UIAbility组件和ExtensionAbility组件都有具体的类承载,支持面向对象的开发方式。开发者可以通过继承和实现相应的类来创建自定义的Ability组件。
1.4 开发流程概述
基于Stage模型开发应用时,涉及以下开发任务。
应用组件开发是核心任务。开发者需要创建UIAbility组件和ExtensionAbility组件,实现各自的生命周期回调方法,处理组件间的跳转和数据传递。
进程模型开发帮助开发者理解Stage模型的进程模型以及几种常用的进程间通信方式。开发者需要了解应用进程的创建和管理机制,以及进程间的通信方法。
线程模型开发帮助开发者理解Stage模型的线程模型以及几种常用的线程间通信方式。开发者需要了解主线程和子线程的分工,以及线程间通信的方法。
应用配置文件开发要求开发者按照Stage模型的要求配置应用配置文件,包括module.json5、app.json5等文件的配置。
二、UIAbility组件详解
2.1 UIAbility的定义与作用
UIAbility组件是包含UI界面的应用组件,主要用于与用户交互。它是系统调度的基本单元,为应用提供绘制界面的窗口。一个UIAbility组件中可以通过多个页面来实现一个功能模块。每一个UIAbility组件实例对应于一个最近任务列表中的任务。
UIAbility组件在HarmonyOS应用中的核心作用体现在以下几个方面。
UIAbility是用户交互的入口。当用户点击应用图标启动应用时,系统会创建并启动对应的UIAbility组件,呈现用户界面。
UIAbility是任务管理的基本单位。每个UIAbility实例对应一个任务,用户在最近任务列表中看到的就是UIAbility的实例。
UIAbility是数据传递的载体。通过Want机制,UIAbility之间可以传递数据和启动参数。
2.2 UIAbility的创建与配置
在DevEco Studio中创建UIAbility组件,步骤如下。
选中对应的模块,单击鼠标右键,选择New > Ability。在弹出的对话框中设置Ability名称,选择是否在设备主屏幕上显示该功能的启动图标,单击Finish完成Ability创建。
创建完成后,系统会自动生成UIAbility的代码文件和配置文件。代码文件位于entry/src/main/ets/entryability目录下,配置文件中的abilities字段会添加对应的配置项。
UIAbility的配置主要在module.json5文件中完成。主要的配置项包括。
name是UIAbility的组件名称,必须与代码中的类名一致。srcEntry是UIAbility的入口文件路径。description是UIAbility的描述信息。icon是UIAbility的图标。label是UIAbility的标签。visible表示UIAbility是否对其他应用可见。
2.3 UIAbility的基本结构
一个标准的UIAbility代码结构如下。
import AbilityConstant from '@ohos.app.ability.AbilityConstant'; import hilog from '@ohos.hilog'; import UIAbility from '@ohos.app.ability.UIAbility'; import Want from '@ohos.app.ability.Want'; import window from '@ohos.window'; export default class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); } onDestroy(): void { hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy'); } onWindowStageCreate(windowStage: window.WindowStage): void { hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); windowStage.loadContent('pages/Index', (err, data) => { if (err.code) { hilog.error(0x0000, 'testTag', 'Failed to load the content. %{public}s', JSON.stringify(err) ?? ''); return; } hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. %{public}s', JSON.stringify(data) ?? ''); }); } onWindowStageDestroy(): void { hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); } onForeground(): void { hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground'); } onBackground(): void { hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground'); } }2.4 UIAbility的启动与销毁
启动UIAbility有多种方式。应用内启动是最常见的方式,通过UIAbilityContext的startAbility方法可以启动当前应用内的其他UIAbility。跨应用启动可以启动其他应用的UIAbility,需要指定目标应用的bundleName和abilityName。通过Want隐式启动不指定具体的abilityName,由系统匹配可以处理该Want的UIAbility。
销毁UIAbility的方式也有多种。主动销毁通过调用terminateSelf方法可以主动销毁当前UIAbility。系统销毁当系统资源不足或用户从最近任务列表中移除应用时,系统会自动销毁UIAbility。
2.5 一个应用有多个UIAbility
一个应用可以有一个UIAbility,也可以有多个UIAbility。多UIAbility的设计使得复杂应用能够将不同功能模块独立管理,提高代码的可维护性和运行时的独立性。
多UIAbility的好处包括:功能模块解耦,不同功能模块可以独立开发和维护;任务独立,每个UIAbility在最近任务列表中独立显示;故障隔离,一个UIAbility的崩溃不会影响其他UIAbility;资源独立,每个UIAbility可以独立管理自己的资源。
在实际开发中,推荐将一个应用的主要功能模块分别设计为独立的UIAbility。例如,一个电商应用可以将首页、商品详情、购物车、个人中心分别设计为独立的UIAbility。
三、Ability生命周期深入解析
3.1 生命周期概述
UIAbility的生命周期管理是应用开发的核心内容。开发者需要理解生命周期的各个阶段,在适当的时机执行初始化和资源释放操作。
UIAbility的生命周期有四个核心状态:Create、Foreground、Background、Destroy。
Create状态在UIAbility实例创建时触发,对应onCreate回调。Foreground状态在UIAbility从后台切换到前台时触发,对应onForeground回调。Background状态在UIAbility从前台切换到后台时触发,对应onBackground回调。Destroy状态在UIAbility实例销毁时触发,对应onDestroy回调。
3.2 onCreate回调详解
onCreate回调在UIAbility实例创建时触发,是执行初始化操作的最佳时机。
onCreate回调的主要用途包括:初始化页面数据,定义变量、加载初始数据;申请系统资源,如数据库连接、文件句柄等;注册事件监听,如网络状态变化监听、系统配置变化监听等。
需要注意的是,onCreate回调中应避免执行耗时操作,否则会影响应用的启动速度。对于耗时操作,应使用异步方式执行。
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { // 初始化页面数据 this.initData(); // 申请系统资源 this.requestPermissions(); // 注册事件监听 this.registerEventListeners(); }3.3 onForeground和onBackground回调详解
onForeground回调在UIAbility从后台切换到前台时触发,是恢复资源和更新UI的时机。典型操作包括:恢复动画和定时器,重新申请在onBackground中释放的资源,如相机、定位等;刷新UI数据,确保用户看到最新内容。
onBackground回调在UIAbility从前台切换到后台时触发,是释放资源和保存状态的时机。典型操作包括:释放不必要的资源,如停止动画、释放相机等;保存应用状态,以便下次恢复时使用;暂停网络请求和定时任务。
onForeground(): void { // 恢复动画 this.resumeAnimations(); // 重新申请资源 this.requestCamera(); // 刷新数据 this.refreshData(); } onBackground(): void { // 释放资源 this.releaseCamera(); // 保存状态 this.saveState(); // 暂停任务 this.pauseBackgroundTasks(); }3.4 onWindowStageCreate和onWindowStageDestroy回调详解
onWindowStageCreate回调在UIAbility实例创建后、进入前台之前触发,是设置UI的时机。
onWindowStageCreate的主要用途包括:加载页面内容,通过windowStage.loadContent加载指定的页面;订阅窗口事件,监听窗口的焦点变化、可见性变化等;初始化窗口属性,设置窗口的背景色、亮度、方向等属性。
onWindowStageCreate(windowStage: window.WindowStage): void { // 订阅窗口事件 windowStage.on('windowStageEvent', (data) => { // 处理窗口事件 }); // 加载页面 windowStage.loadContent('pages/Index', (err, data) => { // 处理加载结果 }); }onWindowStageDestroy回调在UIAbility销毁前触发,是释放窗口相关资源的时机。在onWindowStageDestroy中,应该取消窗口事件的订阅,释放与窗口相关的资源。
3.5 onDestroy回调详解
onDestroy回调在UIAbility实例销毁时触发,是进行最终清理的时机。
典型操作包括:释放全局资源,如关闭数据库连接、释放大对象等;取消全局事件监听,防止内存泄漏;保存最终状态,确保数据不丢失。
onDestroy(): void { // 关闭数据库连接 this.closeDatabase(); // 取消事件监听 this.unregisterEventListeners(); // 保存最终状态 this.saveFinalState(); }3.6 生命周期与WindowStage的联动
UIAbility的生命周期与WindowStage的生命周期紧密相关。其关联关系体现在以下方面。
UIAbility创建后、进入前台之前,系统会创建WindowStage实例并触发onWindowStageCreate回调。UIAbility进入前台后,WindowStage变为可见状态。UIAbility进入后台后,WindowStage变为不可见状态。UIAbility销毁前,系统会触发onWindowStageDestroy回调,然后销毁WindowStage实例。
3.7 不同启动场景下的生命周期流程
UIAbility的生命周期流程因启动场景不同而有所差异。
首次启动场景的生命周期流程为:onCreate、onWindowStageCreate、onForeground。这是最常见的启动场景,用户点击应用图标启动应用时触发。
切换到前台场景:当UIAbility从后台切换到前台时,会依次触发onNewWant、onForeground。如果UIAbility已经存在且启动模式为单例,再次启动时会触发onNewWant而不是onCreate。
切换到后台场景:当UIAbility从前台切换到后台时,会触发onBackground。
销毁场景:当UIAbility被销毁时,会触发onWindowStageDestroy、onDestroy。
UIAbility启动到后台的特殊场景:当通过startAbilityByCall接口启动UIAbility到后台时,系统会依次触发onCreate、onBackground,而不会执行onWindowStageCreate。当用户将UIAbility拉到前台时,系统会依次触发onNewWant、onWindowStageCreate、onForeground。
四、Ability之间的跳转与数据传递
4.1 页面跳转的基本概念
在HarmonyOS应用中,Ability之间的跳转是实现应用功能流程的关键机制。无论是应用内的页面切换,还是跨应用的功能调用,本质上都是通过Ability跳转实现的。
Ability跳转的核心是Want对象。Want是组件间信息传递的载体,描述了操作目标、操作意图和附加数据。
4.2 应用内Ability跳转
应用内跳转是最常见的Ability跳转场景。通过指定bundleName和abilityName,可以精准启动目标Ability。
import { Want } from '@kit.AbilityKit'; let want: Want = { deviceId: '', // deviceId为空表示本设备 bundleName: 'com.example.myapplication', abilityName: 'SecondAbility', }; this.context.startAbility(want).then(() => { // 启动成功 }).catch((err) => { // 启动失败 hilog.error(0x0000, 'testTag', 'startAbility failed: %{public}s', JSON.stringify(err)); });需要注意的是,从API 12开始,已不再推荐三方应用使用指定Ability方式(即显式Want)拉起其他应用,推荐通过指定应用链接的方式来实现。
4.3 跨应用Ability跳转
跨应用跳转需要指定目标应用的bundleName和abilityName。如果目标应用未安装,启动会失败。
let want: Want = { deviceId: '', bundleName: 'com.example.targetapp', abilityName: 'com.example.targetapp.MainAbility', }; this.context.startAbility(want).then(() => { // 启动成功 }).catch((err) => { // 启动失败,可能目标应用未安装 hilog.error(0x0000, 'testTag', 'startAbility failed: %{public}s', JSON.stringify(err)); });4.4 隐式Want与显式Want
Want分为显式Want和隐式Want两种类型。
显式Want在启动目标应用组件时,调用方传入的want参数中指定了abilityName和bundleName,称为显式Want。显式Want通常用于应用内组件启动,当有明确处理请求的对象时,是一种简单有效的启动方式。
隐式Want在启动目标应用组件时,调用方传入的want参数中未指定abilityName,称为隐式Want。当需要处理的对象不明确时,可以使用隐式Want,在当前应用中使用其他应用提供的某个能力,而不关心提供该能力的具体应用。
根据系统中待匹配应用组件的匹配情况不同,使用隐式Want启动应用组件时会出现三种情况:未匹配到满足条件的应用组件导致启动失败;匹配到一个满足条件的应用组件,直接启动该应用组件;匹配到多个满足条件的应用组件,弹出选择框让用户选择。
4.5 页面间数据传递
在Ability跳转时,可以通过Want的parameters字段传递数据。
发送端传递数据的示例:
let want: Want = { deviceId: '', bundleName: 'com.example.myapplication', abilityName: 'SecondAbility', parameters: { 'key1': 'value1', 'key2': 100, 'key3': true } }; this.context.startAbility(want);接收端获取数据的示例:
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { let value1 = want.parameters?.['key1'] as string; let value2 = want.parameters?.['key2'] as number; let value3 = want.parameters?.['key3'] as boolean; // 使用获取的数据 }4.6 带回调的跳转与结果返回
有时需要在启动目标Ability后,等待目标Ability处理完成并返回结果。这时可以使用startAbilityForResult方法。
启动端代码:
this.context.startAbilityForResult(want).then((result) => { if (result.resultCode === 0) { // 处理成功结果 let data = result.want?.parameters; } else { // 处理失败 } });目标端返回结果的代码:
// 在目标Ability中 this.context.terminateSelfWithResult({ resultCode: 0, want: { parameters: { 'resultKey': 'resultValue' } } });五、Want机制完全指南
5.1 Want的核心结构
Want是对象类型,核心字段决定组件匹配与启动逻辑。
deviceId表示目标设备ID,空字符串表示本机,跨设备场景需指定设备标识。隐式Want暂不支持跨设备调用。
bundleName表示目标应用包名,显式Want必须指定。
abilityName表示目标组件名称,显式Want核心字段。从API 12开始,跨应用场景不推荐使用。
moduleName表示目标模块名称,同一应用多模块存在重名组件时需指定。
uri表示统一资源标识符,格式为scheme://host:port/path。自定义scheme不可与系统应用重复。
action表示操作意图,如ohos.want.action.viewData、ohos.want.action.share等。
entities表示组件类别约束,如entity.system.browsable、entity.system.home等。
type表示数据MIME类型,如text/plain、image/png等,需与uri协同匹配。
parameters表示自定义附加数据,支持基础数据类型。
5.2 隐式Want的匹配规则
隐式Want的匹配规则较为复杂,理解这些规则对于正确使用隐式Want至关重要。
匹配的基础前提是:若action、entities、uri、type、parameters中的linkFeature五个属性均未配置,系统直接判定匹配失败。
匹配优先级从高到低为:linkFeature → action → entities → uri + type。linkFeature是API 11+新增的最高优先级匹配字段,通过parameters传递,用于精准隐式调用。
linkFeature匹配采用精准匹配规则,调用方传递的linkFeature值需与skills配置值完全一致。如果调用方同时传递了uri或type,还需要同时满足scheme或type的匹配。
action匹配规则中,若调用方action为空而目标方skills.actions非空,匹配成功;若调用方action非空而目标方actions为空,匹配失败;若调用方action非空且目标方actions包含调用方action,匹配成功。
entities匹配规则要求目标方entities完全包含调用方entities,缺一不可。
uri和type匹配采用协同校验,根据不同场景有不同规则。
5.3 显式Want的使用场景与限制
显式Want适用于应用内组件启动。通过在Want对象内指定本应用的bundleName和abilityName,可以精准启动目标组件。
显式Want的主要限制在于:从API 12开始,不再推荐三方应用使用指定Ability方式(即显式Want)拉起其他应用,推荐通过指定应用链接的方式来实现。
5.4 隐式Want的常见场景
隐式Want常用于以下场景。
打开链接。通过指定uri和action,让系统匹配可以打开该链接的应用。
分享内容。通过指定action为ohos.want.action.share,让系统匹配可以分享内容的应用。
搜索功能。通过指定action为ohos.want.action.search,让系统匹配可以执行搜索的应用。
六、Ability的启动模式
6.1 启动模式概述
UIAbility的启动模式决定了UIAbility实例的创建和管理方式。HarmonyOS提供了多种启动模式,适用于不同的业务场景。
6.2 singleton模式
singleton模式是默认的启动模式。在该模式下,UIAbility只会在首次启动时创建一个实例,后续启动都会复用该实例。
singleton模式的优势是节省内存和资源,适合大多数普通页面。缺点是如果需要在不同启动场景下加载不同数据,需要手动处理数据更新。
在singleton模式下,当UIAbility已存在时再次启动,不会触发onCreate和onWindowStageCreate,而是触发onNewWant回调。开发者可以在onNewWant中更新数据和UI。
6.3 standard模式
standard模式是每次启动都会创建新的UIAbility实例。在standard模式下,每个启动请求都会生成一个新的实例,各自独立管理。
standard模式适用于需要独立状态管理的场景,如文档编辑器、独立任务等。缺点是内存消耗较大。
6.4 multiton模式
multiton模式允许同一个UIAbility有多个实例,但会复用已存在的实例。这种模式介于singleton和standard之间,在某些复杂场景下有用。
6.5 启动模式的选择建议
对于大多数普通页面,推荐使用singleton模式。对于需要独立状态管理的场景,推荐使用standard模式。对于复杂任务管理场景,可以考虑multiton模式。
七、Ability与WindowStage的联动
7.1 WindowStage概述
WindowStage是UIAbility实例绑定的窗口管理器,起到了应用进程内窗口管理器的作用。它包含一个主窗口,为ArkUI提供了绘制区域。
每个UIAbility实例在创建后、进入前台之前,系统会创建一个WindowStage实例并触发onWindowStageCreate回调。
7.2 WindowStage的生命周期
WindowStage的生命周期与UIAbility紧密相关。
WindowStage的创建时机是UIAbility创建后、进入前台之前,此时触发onWindowStageCreate回调。开发者可以在onWindowStageCreate中加载页面内容和订阅窗口事件。
WindowStage的销毁时机是UIAbility销毁前,此时触发onWindowStageDestroy回调。开发者可以在onWindowStageDestroy中释放窗口相关资源。
WindowStage的焦点状态包括ACTIVE获得焦点和INACTIVE失去焦点两种状态,可以通过windowStage.on('windowStageEvent')订阅这些事件。
7.3 窗口事件订阅
在onWindowStageCreate中,开发者可以订阅窗口事件。
windowStage.on('windowStageEvent', (data) => { let stageEventType: window.WindowStageEventType = data; switch (stageEventType) { case window.WindowStageEventType.SHOWN: // 切换到前台 break; case window.WindowStageEventType.ACTIVE: // 获得焦点 break; case window.WindowStageEventType.INACTIVE: // 失去焦点 break; case window.WindowStageEventType.HIDDEN: // 切换到后台 break; } });7.4 页面的加载与切换
在onWindowStageCreate中,通过windowStage.loadContent方法加载页面。
windowStage.loadContent('pages/Index', (err, data) => { if (err.code) { hilog.error(0x0000, 'testTag', 'Failed to load the content. %{public}s', JSON.stringify(err) ?? ''); return; } hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. %{public}s', JSON.stringify(data) ?? ''); });在应用运行过程中,可以通过页面路由切换不同的页面,而不需要重新加载整个UIAbility。
7.5 多窗口管理
HarmonyOS支持多窗口管理,一个UIAbility可以创建和管理多个窗口。
创建新窗口的示例:
let windowStage = this.context.windowStage; windowStage.createWindow('newWindow', (err, window) => { // 新窗口创建成功 window.setUIContent('pages/NewPage'); window.showWindow(); });八、ExtensionAbility组件
8.1 ExtensionAbility概述
ExtensionAbility是Stage模型中提供特定场景扩展能力的应用组件。开发者并不直接从ExtensionAbility派生,而是需要使用ExtensionAbility组件的派生类。
ExtensionAbility组件的派生类实例由用户触发创建,并由系统管理生命周期。在Stage模型上,三方应用开发者不能开发自定义服务,而需要根据自身的业务场景通过ExtensionAbility组件的派生类来实现。
8.2 ExtensionAbility的类型
目前支持的ExtensionAbility类型包括。
FormExtensionAbility用于卡片场景,支持桌面卡片的创建、更新和删除。当用户在桌面创建应用的卡片时,需要应用开发者从FormExtensionAbility派生并实现相应的回调函数。
InputMethodExtensionAbility用于输入法场景,支持输入法的实现和切换。
WorkSchedulerExtensionAbility用于闲时任务场景,支持在设备空闲时执行后台任务。
BackupExtensionAbility用于备份及恢复应用数据的能力。
8.3 FormExtensionAbility开发
FormExtensionAbility是卡片开发的核心组件。开发卡片需要完成以下步骤。
配置form_config.json文件,定义卡片的布局、尺寸、更新策略等属性。
创建卡片的ArkUI布局文件。
实现FormController,处理卡片的创建、更新、删除等事件。
在module.json5中注册FormExtensionAbility组件。
8.4 ExtensionAbility的生命周期
不同类型的ExtensionAbility有不同的生命周期回调。
以FormExtensionAbility为例,主要生命周期回调包括:onCreate在卡片实例创建时触发,onUpdate在卡片需要更新时触发,onDelete在卡片被删除时触发。
九、AbilityStage与Context
9.1 AbilityStage概述
AbilityStage是每个Entry或Feature类型HAP在运行期的类实例。当HAP中的代码首次被加载到进程中时,系统会先创建AbilityStage实例。
AbilityStage的主要职责包括:管理该HAP中的所有UIAbility组件,提供组件创建的生命周期回调;处理应用级别的初始化逻辑,如全局配置加载、环境初始化等;管理HAP级别的资源和数据。
9.2 Context概述
Context及其派生类向开发者提供在运行期可以调用的各种资源和能力。UIAbility组件和各种ExtensionAbility组件的派生类都有各自不同的Context类,它们都继承自基类Context,各自根据所属组件提供不同的能力。
9.3 Context的类型
不同类型的Context提供不同的能力。
UIAbilityContext用于UIAbility组件,提供启动Ability、获取应用信息、管理窗口等能力。
ExtensionAbilityContext用于ExtensionAbility组件,提供扩展能力相关的操作。
AbilityStageContext用于AbilityStage,提供应用级的能力访问。
ApplicationContext用于整个应用,提供应用级别的资源访问和生命周期监听。
9.4 Context的常用操作
通过Context可以执行多种操作。
启动Ability是最常用的操作,通过context.startAbility可以启动其他UIAbility。
获取应用信息可以通过context.getApplicationInfo获取应用的包名、版本等信息。
获取资源可以通过context.resourceManager获取字符串、图片等资源。
十、进程模型与线程模型
10.1 进程模型概述
HarmonyOS的进程模型决定了应用组件如何在系统中运行。理解进程模型对于应用性能优化和故障排查非常重要。
在Stage模型中,每个应用组件运行在独立的进程中。应用可以配置多个进程,不同组件可以在不同进程中运行。
进程的创建和管理由系统统一负责。当应用组件被启动时,系统会创建对应的进程;当应用组件被销毁时,系统会回收进程。
10.2 进程间通信
HarmonyOS提供了多种进程间通信方式。
Want是用于组件间通信的标准机制,支持同一设备或跨设备的组件启动和数据传递。
IPC用于跨进程的远程调用,支持同步和异步两种模式。
EventHub用于进程间的事件发布和订阅。
10.3 线程模型概述
HarmonyOS的线程模型决定了应用代码的执行方式。理解线程模型对于性能优化和并发处理非常重要。
HarmonyOS应用采用多线程模型。主线程负责UI渲染和用户交互,子线程负责执行耗时任务。
UIAbility在单独的主线程中运行。主线程中的所有操作都会影响UI响应性,因此耗时操作必须放到子线程中执行。
10.4 主线程与子线程的分工
主线程负责UI渲染、事件分发、生命周期管理等任务。主线程的任务必须快速完成,否则会导致UI卡顿。
子线程负责执行网络请求、数据库操作、复杂计算等耗时任务。子线程的任务不会影响主线程的响应性。
HarmonyOS提供了多种创建子线程的方式:TaskPool用于执行可并行的任务;Worker用于执行独立的脚本;Thread用于直接操作线程。
10.5 线程间通信
HarmonyOS提供了多种线程间通信方式。
Emitter用于线程间的事件发布和订阅,支持一对多的通信模式。
Worker通过postMessage和onmessage实现双向通信。
TaskPool通过任务提交和结果回调实现线程间通信。
十一、应用配置文件详解
11.1 配置文件概述
HarmonyOS应用通过配置文件定义应用的基本信息、组件信息、权限信息等。配置文件是应用开发的重要组成部分。
主要的配置文件包括:app.json5应用级配置文件,定义应用的包名、版本、图标等信息;module.json5模块级配置文件,定义模块的名称、类型、设备类型、组件信息等;build-profile.json5构建配置文件,定义构建相关的配置。
11.2 app.json5详解
app.json5是应用级配置文件,位于AppScope目录下。
主要字段包括:bundleName是应用包名,必须唯一;versionCode是版本号,用于应用升级;versionName是版本名称,显示给用户;icon是应用图标;label是应用名称;vendor是应用供应商。
11.3 module.json5详解
module.json5是模块级配置文件,位于entry/src/main目录下。
主要字段包括:name是模块名称;type是模块类型,Entry或Feature;deviceTypes是支持的设备类型;abilities是UIAbility组件配置;extensionAbilities是ExtensionAbility组件配置。
abilities配置项包括:name是UIAbility组件名称;srcEntry是入口文件路径;icon是图标;label是标签;visible是否对其他应用可见;skills是隐式Want匹配配置。
11.4 skills配置详解
skills配置用于隐式Want匹配。主要的配置项包括。
actions定义了该组件支持的action,多个action可以同时配置。
entities定义了该组件支持的entity类别。
uris定义了该组件支持的uri匹配规则,包括scheme、host、port、path等。
11.5 配置文件的开发规范
在开发配置文件时,需要注意以下规范:bundleName必须唯一,建议使用反向域名格式;versionCode每次发布新版本时递增;abilities的name必须在应用内唯一;skills配置需要与隐式Want的匹配规则对应。
十二、跨设备Ability迁移与接续
12.1 跨设备迁移概述
HarmonyOS支持将应用从一个设备迁移到另一个设备,实现跨设备的状态接续。这是HarmonyOS分布式能力的核心体现。
跨设备迁移允许用户在一台设备上开始使用应用,在另一台设备上继续使用,而不会丢失中间状态。
12.2 迁移的基本流程
跨设备迁移的基本流程如下。
源端收到迁移请求后,调用方通过continueAbility或startAbilityByCall触发迁移。源端Ability收到迁移请求后,系统会触发continueRequestReceived信号。
源端序列化状态后,在continueRequestReceived中,开发者需要将当前UI状态和数据序列化,然后响应迁移请求。如果同意迁移,调用setAgreeResponse并传递序列化的数据。
目标端接收并恢复状态。目标端通过newWantInfoReceived信号接收迁移请求,从中提取数据并恢复UI状态。
12.3 源端实现
源端实现迁移的主要步骤包括。
监听迁移请求是第一步,需要连接continueRequestReceived信号。
校验版本和业务条件,检查sourceApplicationVersionCode是否与当前版本匹配。
序列化状态并响应是核心步骤。如果版本匹配,调用setAgreeResponse(serialized)同意迁移。如果版本不匹配,调用setMismatchResponse。也可以调用setRejectResponse拒绝迁移。
控制源端是否保留。调用setExitAppOnSourceDeviceAfterMigration可以控制源端是否在成功迁移后退出。默认值为true表示退出。
动态开关迁移能力。调用setContinuationActive可以动态开启或关闭迁移能力。
12.4 目标端实现
目标端实现迁移的主要步骤包括。
处理冷启动场景,如果应用是从迁移请求冷启动的,可以通过getAppLaunchWantInfo获取启动Want,然后提取迁移数据。
处理热启动场景,如果应用已在后台运行,可以通过newWantInfoReceived信号接收迁移请求。检查launchReason是否为Continuation来确认这是迁移场景。
提取并恢复数据。使用tryGetOnContinueData从Want中提取迁移数据,然后反序列化并恢复UI状态。
12.5 快速预热机制
ContinueQuickStart是HarmonyOS提供的快速预热机制。其工作原理如下。
目标端先触发PrepareContinuation预热,界面快速占位,让用户看到即时反馈。随后系统触发Continuation正式数据迁移,将完整状态恢复到目标端。
区分预热与正式数据的方法是通过检查launchReason来区分PrepareContinuation和Continuation两种场景。
12.6 迁移注意事项
在实现跨设备迁移时,需要注意以下事项。
显式响应迁移请求非常重要。未响应迁移请求默认视为拒绝,务必在回调中明确处理。
线程安全同样值得注意。回调在应用主线程执行,但仍需避免耗时的同步操作阻塞UI。
数据大小限制也不能忽视。目前仅支持小于100KB的数据传输,超出此限制可能会导致迁移失败。
向前兼容性同样重要。迁移数据建议携带版本号,以便目标端处理来自旧版本源端的接续数据。
12.7 跨设备迁移的完整示例
源端代码示例:
// 源端 Ability onContinue(wantParam: Record<string, Object>): AbilityConstant.OnContinueResult { // 准备迁移数据 let data = this.saveState(); wantParam['migrationData'] = data; return AbilityConstant.OnContinueResult.AGREE; }目标端代码示例:
// 目标端 Ability onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { if (launchParam.launchReason === AbilityConstant.LaunchReason.CONTINUATION) { // 这是跨设备迁移场景 let data = want.parameters?.['migrationData']; if (data) { this.restoreState(data); } } }总结
本文深入讲解了Stage应用模型与Ability开发的核心知识。从Stage模型的架构设计到UIAbility组件的完整生命周期,从Ability之间的跳转与数据传递到Want机制的完全指南,从进程模型与线程模型到跨设备Ability迁移与接续,本文覆盖了Stage应用模型开发的各个方面。
通过本文的学习,希望你能够理解Stage模型的设计理念和架构优势,掌握UIAbility组件的创建、配置和生命周期管理方法,熟练使用Want机制进行Ability之间的跳转和数据传递,了解进程模型和线程模型的基本概念,掌握应用配置文件的配置方法。
Stage模型是HarmonyOS应用开发的核心架构,理解Stage模型是掌握鸿蒙开发的关键。第三篇将深入讲解ArkUI框架与声明式UI开发,包括ArkUI框架概述、基础组件详解、容器组件与布局、状态管理、条件渲染与循环渲染等内容。