第10章开源鸿蒙:部件化结构与Ability框架
理解开源鸿蒙的部件化设计理念、Ability框架的组成与生命周期、Stage模型的架构,以及Ability的分布式能力
第10章 部件化结构与Ability框架
本章目标:理解开源鸿蒙的部件化设计理念、Ability框架的组成与生命周期、Stage模型的架构,以及Ability的分布式能力。
10.1 部件化设计理念
10.1.1 什么是部件化
部件化(Componentization)是软件工程中的一种架构思想:将一个复杂的系统拆分为多个独立的、可复用的、可替换的部件(Component),每个部件负责一个明确的功能。
开源鸿蒙从操作系统内核到应用框架都贯彻了部件化的理念:
内核层面的部件化:
- LiteOS-M的内核模块(任务调度、内存管理、IPC)可以按需裁剪
- HDF驱动框架将驱动视为独立的部件,可以动态加载和卸载
- 系统服务以独立进程运行,一个服务的崩溃不会影响其他服务
应用层面的部件化:
- 应用由多个Ability组成,每个Ability是一个独立的部件
- Ability之间通过标准接口通信,互不直接依赖内部实现
- 应用可以按模块(Module)拆分,按需加载
10.1.2 部件化的好处
可维护性:每个部件职责单一,修改一个部件不影响其他部件。一个有bug的Ability被修复,不需要重新发布整个应用。
可复用性:通用的Ability可以被多个应用复用。例如,一个"图片裁剪"Ability可以被相机应用、社交应用、文档编辑应用共同使用。
可替换性:特定功能的实现可以被替换而不影响使用者。例如,一个应用的音乐播放服务可以替换为另一个更好的实现。
按需加载:不需要的功能可以不加载,节省内存和存储空间。这在资源受限的IoT设备上尤其重要。
10.2 Ability框架概览
10.2.1 什么是Ability
Ability是开源鸿蒙应用的基本组成单元和运行实体。每个Ability都有独立的生命周期,运行在自己的进程中(或线程中)。
一个OpenHarmony应用由以下部分组成:
MyApp.app(应用包)
├── entry模块(入口模块,必需)
│ ├── UIAbility(主界面)
│ └── 其他Ability
├── feature模块(功能模块,可选)
│ ├── UIAbility
│ └── ExtensionAbility
└── shared模块(共享资源,可选)
├── 公共工具类
└── 共享资源文件
10.2.2 Ability的类型
在当前的Stage模型下,Ability分为两大类:
UIAbility:带有用户界面的Ability。
- 每个UIAbility对应一个独立的窗口(WindowStage)
- 用户可以通过UIAbility与应用交互
- 一个应用可以有多个UIAbility,但通常只有一个主UIAbility
- UIAbility之间可以通过路由(Router)或Want进行跳转
ExtensionAbility:特定场景的扩展能力,没有独立的窗口(或窗口由系统管理)。
| ExtensionAbility类型 | 功能 | 典型场景 |
|---|---|---|
| FormExtension | 桌面卡片 | 天气卡片、日历卡片 |
| WorkSchedulerExtension | 后台定时任务 | 定时数据同步、定期检查 |
| InputMethodExtension | 输入法 | 自定义键盘 |
| AccessibilityExtension | 无障碍服务 | 屏幕阅读器 |
| PushExtension | 推送服务 | 接收和处理推送消息 |
| BackgroundTaskExtension | 后台长时任务 | 音乐播放、导航 |
| WindowExtension | 嵌入式窗口 | 悬浮窗、画中画 |
10.3 UIAbility详解
10.3.1 生命周期
UIAbility的生命周期由系统管理,经历以下状态:
Create
↓
WindowStageCreate
↓
┌──────────┐
┌──→│ Foreground│←──┐
│ │ (前台) │ │
│ └─────┬─────┘ │
│ │ │
│ onBackground onForeground
│ │ │
│ ┌─────┴─────┐ │
│ │ Background│───┘
│ │ (后台) │
│ └─────┬─────┘
│ │
│ 系统资源紧张时
│ │
│ ┌─────┴──────┐
└────│ Destroyed │
│ (销毁) │
└────────────┘
各状态说明:
Create(创建):
- 系统创建UIAbility实例
- 应用执行初始化操作(加载资源、初始化数据)
- 回调方法:
onCreate(want, launchParam)
WindowStageCreate(窗口创建):
- 系统为UIAbility创建窗口阶段(WindowStage)
- 在此阶段加载UI内容(通过
loadContent方法) - 回调方法:
onWindowStageCreate(windowStage)
Foreground(前台):
- UIAbility可见且可交互
- 用户可以操作界面
- 回调方法:
onForeground()
Background(后台):
- UIAbility不可见
- 系统可能在资源紧张时回收后台UIAbility
- 回调方法:
onBackground()
WindowStageDestroy(窗口销毁):
- 在UIAbility销毁前,窗口阶段被销毁
- 释放UI相关的资源
- 回调方法:
onWindowStageDestroy(windowStage)
Destroy(销毁):
- UIAbility实例被销毁
- 释放所有资源
- 回调方法:
onDestroy()
10.3.2 生命周期与资源管理
理解生命周期的核心意义在于合理管理资源:
onCreate: 分配必要的资源(但不做耗时操作)
onForeground: 恢复界面更新、启动动画等
onBackground: 暂停界面更新、释放非必要资源
onDestroy: 释放所有资源
常见错误:
- 在
onCreate中执行耗时操作(如网络请求)→ 导致UIAbility启动缓慢 - 在
onBackground后仍然保持高频率的UI更新 → 白白消耗CPU和电量 - 在
onDestroy中不释放资源(如定时器、监听器)→ 内存泄漏
10.3.3 页面路由
一个UIAbility可以包含多个页面(Page),页面之间通过**路由(Router)**进行导航:
UIAbility(入口页面)
│
├── Page1(首页)
│ ├── 跳转到 Page2
│ ├── 跳转到 Page3
│ └── 返回上一页
│
├── Page2(详情页)
│ ├── 跳转到 Page4
│ └── 返回 Page1
│
└── Page3(设置页)
└── 返回 Page1
页面路由的API:
import router from '@ohos.router'
// 跳转到指定页面
router.pushUrl({ url: 'pages/DetailPage', params: { id: 123 } })
// 替换当前页面(不能返回)
router.replaceUrl({ url: 'pages/SettingsPage' })
// 返回上一页
router.back()
// 获取页面参数
let params = router.getParams() // { id: 123 }
页面路由栈是每个UIAbility独立的——不同UIAbility的页面路由栈互不干扰。
10.4 ExtensionAbility详解
10.4.1 FormExtension(桌面卡片)
桌面卡片(Widget/Service Widget)是用户在桌面快速查看信息、执行操作的小型UI。
桌面卡片示例:
┌─────────────┐
│ ☀️ 北京 │
│ 25°C 多云 │
│ H:28° L:20°│
└─────────────┘
(天气卡片,显示在手机桌面)
FormExtension的生命周期:
| 状态 | 说明 |
|---|---|
| onCreate | 卡片被添加到桌面时创建 |
| onCastToNormal | 卡片从临时状态变为常态 |
| onUpdate | 系统定时更新卡片内容 |
| onFormEvent | 卡片上的交互事件 |
| onRemove | 卡片从桌面移除 |
| onDestroy | 卡片被销毁 |
10.4.2 WorkSchedulerExtension(后台定时任务)
WorkSchedulerExtension允许应用在后台定期执行任务,即使应用没有在前台运行。
使用场景:
- 天气应用:每30分钟更新天气数据
- 邮件应用:每15分钟检查新邮件
- 健康应用:每小时同步步数数据
限制:
- 系统对后台任务有严格限制(频率、时长、网络类型)
- 不同设备类型的限制不同(手表比手机更严格)
- 用户可以在设置中关闭应用的后台任务
10.4.3 BackgroundTaskExtension(后台长时任务)
某些应用需要长时间在后台运行(如音乐播放、导航),BackgroundTaskExtension提供这种能力。
与WorkSchedulerExtension的区别:
- WorkSchedulerExtension:短时间、定期执行的任务
- BackgroundTaskExtension:长时间持续运行的任务
系统对长时后台任务的管理:
- 限制同时运行的长时任务数量
- 资源紧张时优先终止低优先级的后台任务
- 用户可以在通知栏管理正在运行的后台任务
10.5 Stage模型
10.5.1 Stage模型是什么
Stage模型是开源鸿蒙当前推荐的应用开发模型,取代了早期的FA(Feature Ability)模型。
"Stage"的含义:舞台。UIAbility就像舞台上的演员——它有出场(Foreground)、退场(Background)、谢幕(Destroy)等状态。
10.5.2 Stage模型 vs FA模型
| 维度 | FA模型(已废弃) | Stage模型(当前) |
|---|---|---|
| 组件类型 | Ability + DataAbility | UIAbility + ExtensionAbility |
| 生命周期 | 简单(Create/Foreground/Background/Destroy) | 完整(增加了WindowStage) |
| 进程模型 | 应用内Ability共享进程 | 每个UIAbility独立进程 |
| UI管理 | 通过Ability直接管理 | 通过WindowStage独立管理 |
| 数据共享 | DataAbility | @Provide/@Consume + AppStorage |
| 多设备 | 有限支持 | 原生支持分布式迁移 |
Stage模型的关键改进:
(1)进程隔离
在FA模型中,同一个应用的所有Ability共享一个进程。一个Ability崩溃可能导致整个应用崩溃。
在Stage模型中,每个UIAbility运行在独立的进程中。一个UIAbility崩溃不会影响应用中的其他UIAbility。
FA模型:
应用进程 ← [Ability1, Ability2, Ability3]
(任何一个崩溃 → 全部崩溃)
Stage模型:
进程1 ← [UIAbility1]
进程2 ← [UIAbility2]
进程3 ← [UIAbility3]
(各自独立,互不影响)
(2)WindowStage独立管理
WindowStage独立于UIAbility的生命周期管理。UIAbility可以在没有WindowStage的情况下运行(如后台服务),也可以有多个WindowStage(如多个窗口)。
(3)增强的组件间通信
Stage模型提供了更丰富的组件间通信方式:
- Emitter:事件总线,支持跨Ability的事件通知
- CommonEvent:公共事件,支持跨应用的事件订阅
- @Provide/@Consume:跨组件层级的状态共享
- AppStorage:应用级别的全局状态管理
10.6 Ability的分布式能力
10.6.1 跨设备Ability调用
Stage模型的一个重要特性是支持跨设备Ability调用——设备A上的应用可以启动设备B上的Ability。
传统模式:
手机上的应用 → 只能启动手机上的Ability
分布式模式:
手机上的应用 → 可以启动平板/手表/电视上的Ability
实现机制:
应用通过Want对象指定目标Ability。Want中可以包含目标设备的ID:
// 启动本地Ability
let want: Want = {
bundleName: 'com.example.app',
abilityName: 'DetailAbility',
// 不指定deviceId → 在本地启动
}
// 启动远程Ability
let remoteWant: Want = {
bundleName: 'com.example.app',
abilityName: 'DetailAbility',
deviceId: 'tablet_device_id' // 指定目标设备
}
// 启动调用(本地和远程使用相同的API)
context.startAbility(remoteWant)
对应用来说,启动本地Ability和远程Ability使用完全相同的API。系统根据Want中是否包含deviceId来决定在本地启动还是跨设备启动。
10.6.2 Ability迁移
Ability迁移是指将一个正在运行的UIAbility从一台设备无缝迁移到另一台设备。
迁移前:
手机:[视频播放UIAbility] ← 用户正在手机上看视频
迁移后:
手机:[视频播放UIAbility已关闭]
电视:[视频播放UIAbility正在运行] ← 视频在电视上继续播放
迁移过程:
步骤1:迁移准备
- 保存UIAbility的当前状态(UI状态、业务数据)
- 建立设备间的迁移通道
步骤2:数据传输
- 将状态数据通过软总线传输到目标设备
- 同时传输必要的资源文件
步骤3:目标设备恢复
- 目标设备上的UIAbility加载数据
- 恢复UI状态
- 如果是视频/音频,切换渲染和输出设备
步骤4:源设备清理
- 源设备上的UIAbility销毁
- 释放资源
迁移的技术挑战:
- 状态一致性:迁移后UIAbility的状态必须与迁移前完全一致
- 无缝体验:迁移过程中的中断时间应该尽可能短(目标是用户无感知)
- 资源适配:不同设备的屏幕尺寸、分辨率不同,UI需要自动适配
- 硬件切换:如果Ability使用了特定硬件(如摄像头),迁移后需要切换到目标设备的硬件
10.6.3 分布式数据在Ability间的共享
Ability的分布式能力与分布式数据管理(第8章)紧密配合:
- 迁移时同步数据:Ability迁移时,其关联的分布式数据也自动同步到目标设备
- 跨设备状态同步:不同设备上的同一Ability实例,可以通过分布式数据共享状态
- 冲突处理:如果两个设备上的同一Ability同时修改共享数据,由分布式数据管理的冲突解决机制处理
10.7 应用间通信
10.7.1 Want机制
Want是开源鸿蒙中应用间通信的基本载体,类似于Android中的Intent。
Want包含的信息:
Want {
bundleName: 'com.example.app' // 目标应用的包名
abilityName: 'DetailAbility' // 目标Ability的名称
moduleName: 'entry' // 目标模块名
deviceId: 'xxx' // 目标设备ID(可选)
uri: 'http://example.com/page' // 数据URI(可选)
type: 'text/plain' // MIME类型(可选)
parameters: { // 附加参数
id: 123,
title: 'Hello'
}
flags: 0 // 标志位
}
Want的用途:
- 启动Ability:通过Want指定要启动的Ability
- 传递数据:通过Want的parameters字段在Ability之间传递数据
- 跨设备调用:通过deviceId字段指定目标设备
10.7.2 公共事件(CommonEvent)
公共事件是系统级别的发布-订阅机制,支持跨应用、跨设备的事件通知。
事件发布者 事件订阅者
│ │
│ publish("EVENT_THEME_CHANGE", │
│ {theme: "dark"}) │
├─────────────────────────────→│
│ │ 收到事件,更新UI
│ │
│ publish("EVENT_NETWORK_LOST") │
├─────────────────────────────→│
│ │ 收到事件,显示提示
系统预定义了一些公共事件(如网络状态变化、电量变化、屏幕旋转等),应用也可以自定义公共事件。
10.8 本章小结
关键要点回顾:
- 部件化是开源鸿蒙贯穿始终的设计理念——从内核模块到系统服务到应用Ability,都是可独立、可复用、可替换的部件
- UIAbility是带界面的Ability,有完整的生命周期(Create→WindowStageCreate→Foreground↔Background→Destroy)
- ExtensionAbility是无界面或系统管理的扩展能力(卡片、后台任务、输入法等)
- Stage模型取代FA模型,关键改进:进程隔离、WindowStage独立管理、增强的组件间通信
- Want机制是应用间通信的基本载体,支持传递数据、指定目标Ability和目标设备
- 分布式能力:跨设备Ability调用、Ability迁移、跨设备状态同步
下一章预告:第11章将分析开源鸿蒙的安全子系统——TEE、沙箱、权限管理、安全启动等安全机制的实现原理。
更多推荐



所有评论(0)