第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 本章小结

关键要点回顾

  1. 部件化是开源鸿蒙贯穿始终的设计理念——从内核模块到系统服务到应用Ability,都是可独立、可复用、可替换的部件
  2. UIAbility是带界面的Ability,有完整的生命周期(Create→WindowStageCreate→Foreground↔Background→Destroy)
  3. ExtensionAbility是无界面或系统管理的扩展能力(卡片、后台任务、输入法等)
  4. Stage模型取代FA模型,关键改进:进程隔离、WindowStage独立管理、增强的组件间通信
  5. Want机制是应用间通信的基本载体,支持传递数据、指定目标Ability和目标设备
  6. 分布式能力:跨设备Ability调用、Ability迁移、跨设备状态同步

下一章预告:第11章将分析开源鸿蒙的安全子系统——TEE、沙箱、权限管理、安全启动等安全机制的实现原理。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐