阅读时长:约 18 分钟 | 难度:★★★★☆ | 篇章:第 1 篇 · 项目架构与设计哲学 对应源码:
entry/src/main/ets/entryability/EntryAbility.ets、entrybackupability/EntryBackupAbility.ets
前言
在 HarmonyOS Stage 模型下,Ability是应用的功能载体。一个应用可以包含一个或多个 UIAbility,每个 UIAbility 实例对应一个任务。玄象项目作为单入口应用,采用了“一个 EntryAbility + 一个 EntryBackupAbility 扩展能力“的最小化设计。本篇将深入剖析玄象项目的 Ability 设计决策:何时该用单 Ability、何时该拆分多 Ability、备份扩展能力如何接入。
提示:Ability 数量直接决定了应用的任务管理行为、跨设备迁移能力、内存占用水平。错误的 Ability 拆分策略会导致用户体验割裂。
一、Ability 分类与玄象项目选择
1.1 HarmonyOS Ability 分类
HarmonyOS 提供两类 Ability:
| 类型 | 职责 | 是否有 UI | 典型场景 |
|---|---|---|---|
| UIAbility | 包含 UI 界面的能力 | 是 | 主入口、设置页、独立功能区 |
| ExtensionAbility | 无 UI 的扩展能力 | 否 | 备份、卡片服务、输入法 |
1.2 玄象项目的 Ability 配置
玄象项目在module.json5中声明了 2 个 Ability:
{ "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": ["ohos.want.action.home"] } ] } ], "extensionAbilities": [ { "name": "EntryBackupAbility", "srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets", "type": "backup", "exported": false, "metadata": [ { "name": "ohos.extension.backup", "resource": "$profile:backup_config" } ] } ] }1.3 选择单 UIAbility 的考量
玄象项目选择单一 EntryAbility的核心考量:
- 单入口应用:玄象所有功能均从首页九宫格进入,无独立入口。
- 统一任务栈:所有页面在同一任务中,返回行为一致。
- 简化生命周期:单一 Ability 减少生命周期回调的复杂度。
- 降低内存占用:多 Ability 会创建多任务实例,增加内存压力。
提示:如果玄象未来推出“独立罗盘“功能,希望用户从桌面直接进入罗盘界面(而非通过首页),此时应该新增一个
LuopanAbility。
二、EntryAbility 深度解析
2.1 完整源码
import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; import { window } from '@kit.ArkUI'; const DOMAIN = 0x0000; export default class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { try { this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); } catch (err) { hilog.error(DOMAIN, 'testTag', 'Failed to set colorMode. Cause: %{public}s', JSON.stringify(err)); } hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); } onDestroy(): void { hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy'); } onWindowStageCreate(windowStage: window.WindowStage): void { 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 { hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); } onForeground(): void { hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground'); } onBackground(): void { hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground'); } }2.2 import 语句解析
import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; import { hilog } from '@kit.PerformanceAnalysisKit'; import { window } from '@kit.ArkUI';玄象项目引入了三个 Kit:
| Kit | 用途 | 玄象使用 |
|---|---|---|
@kit.AbilityKit | Ability 能力 | UIAbility基类、Want参数 |
@kit.PerformanceAnalysisKit | 性能分析 | hilog日志 |
@kit.ArkUI | ArkUI 框架 | window.WindowStage |
2.3 DOMAIN 日志域
const DOMAIN = 0x0000;玄象项目使用0x0000作为日志域。hilog是 HarmonyOS 的官方日志系统,通过DOMAIN与tag双重标识日志来源。
提示:生产环境建议为不同模块分配不同的
DOMAIN(如 0x0001 为入口、0x0002 为星宿模块),便于日志过滤与排查。
2.4 onCreate 初始化
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { try { this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); } catch (err) { hilog.error(DOMAIN, 'testTag', 'Failed to set colorMode. Cause: %{public}s', JSON.stringify(err)); } hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate'); }玄象项目在onCreate中做了两件事:
- 设置颜色模式:调用
setColorMode(COLOR_MODE_NOT_SET),表示跟随系统颜色模式。 - 输出日志:记录 Ability 创建事件。
try-catch包裹的意义:setColorMode在某些低版本系统上可能抛出异常,玄象项目通过try-catch防止应用崩溃。这是 HarmonyOS 应用兼容性处理的典型范式。
2.5 onWindowStageCreate 加载首页
onWindowStageCreate(windowStage: window.WindowStage): void { 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.'); }); }onWindowStageCreate是 UIAbility 最关键的回调,玄象项目在此加载首页pages/Index。
loadContent回调规范:
- 检查 err.code:非 0 表示加载失败。
- 错误日志:用
JSON.stringify(err)输出完整错误信息。 - 成功日志:记录加载成功事件。
提示:玄象项目的
pages/Index内部用Navigation包裹了SplashPage,启动页加载完后replaceUrl到HomePage。这种“启动页 → 首页“的 3 秒过渡是玄象项目精心设计的用户体验。
三、EntryBackupAbility 备份扩展能力
3.1 完整源码
import { hilog } from '@kit.PerformanceAnalysisKit'; import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; const DOMAIN = 0x0000; export default class EntryBackupAbility extends BackupExtensionAbility { async onBackup() { hilog.info(0x0000, 'testTag', 'onBackup ok'); await Promise.resolve(); } async onRestore(bundleVersion: BundleVersion) { hilog.info(0x0000, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion)); await Promise.resolve(); } }3.2 BackupExtensionAbility 的作用
BackupExtensionAbility是 HarmonyOS 提供的云端备份扩展能力,允许应用在系统备份/恢复时介入处理:
onBackup:系统备份时回调,应用可在此保存关键状态。onRestore:系统恢复时回调,应用可在此恢复数据并处理版本迁移。
3.3 备份配置文件
玄象项目在module.json5中引用了$profile:backup_config,该配置文件位于resources/base/profile/backup_config.json:
{ "allowToBackupRestore": true }配置项说明:
| 字段 | 类型 | 说明 |
|---|---|---|
allowToBackupRestore | boolean | 是否允许备份恢复 |
提示:玄象项目当前
onBackup/onRestore仅输出日志,未做实质性数据处理。未来可在onBackup中保存用户偏好(如主题色、字体大小),在onRestore中恢复这些偏好。
四、UIAbility 生命周期详解
4.1 生命周期总览
玄象项目 EntryAbility 实现了全部 6 个生命周期回调:
应用启动 ↓ onCreate ← Ability 创建,初始化配置 ↓ onWindowStageCreate ← 窗口创建,加载首页 ↓ [用户使用应用] ↓ onForeground ← 切到前台 ↓ onBackground ← 切到后台 ↓ [用户切回应用] ↓ onWindowStageDestroy ← 窗口销毁 ↓ onDestroy ← Ability 销毁4.2 生命周期回调清单
| 回调 | 触发时机 | 玄象用途 | 典型操作 |
|---|---|---|---|
onCreate | Ability 创建 | 设置颜色模式 | 全局配置初始化 |
onDestroy | Ability 销毁 | 输出日志 | 资源释放 |
onWindowStageCreate | 窗口创建 | 加载pages/Index | loadContent |
onWindowStageDestroy | 窗口销毁 | 输出日志 | UI 资源释放 |
onForeground | 切到前台 | 输出日志 | 恢复计时器、刷新数据 |
onBackground | 切到后台 | 输出日志 | 暂停计时器、保存状态 |
4.3 玄象项目生命周期最佳实践
玄象项目在生命周期回调中遵循以下原则:
onCreate只做轻量初始化:避免阻塞应用启动。onWindowStageCreate加载首页:使用loadContent异步加载。onForeground/onBackground处理状态切换:恢复/暂停计时器。onDestroy释放资源:清理定时器、关闭文件句柄。
五、Want 与启动参数
5.1 Want 的概念
Want是 HarmonyOS 中描述“想要做什么“的对象,用于 Ability 间通信。玄象项目的 EntryAbility 通过skills字段声明可接收的 Want:
"skills": [ { "entities": ["entity.system.home"], "actions": ["ohos.want.action.home"] } ]5.2 Want 的核心字段
| 字段 | 类型 | 说明 |
|---|---|---|
bundleName | string | 目标应用包名 |
abilityName | string | 目标 Ability 名称 |
uri | string | 数据 URI |
type | string | 数据 MIME 类型 |
action | string | 操作类型 |
entities | string[] | 实体类别 |
parameters | Record | 自定义参数 |
5.3 onCreate 中接收 Want
玄象项目在onCreate中接收want参数:
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { // want.parameters 可获取外部传入的参数 // 玄象项目当前未使用 want 参数 // ... }提示:如果玄象未来支持“通过通知跳转到特定星宿详情页“,可在通知的 Want 中携带
mansionId参数,EntryAbility 在onCreate中读取并传给首页。
六、context 上下文的能力访问
6.1 context 的核心作用
this.context是 UIAbility 的上下文对象,提供应用级能力访问:
this.context.getApplicationContext().setColorMode(...);6.2 context 提供的关键 API
| API | 用途 |
|---|---|
getApplicationContext() | 获取应用级上下文 |
getFilesDir() | 获取应用文件目录 |
getCacheDir() | 获取缓存目录 |
getExternalFilesDir() | 获取外部存储目录 |
requestPermissionsFromUser() | 动态申请权限 |
terminateSelf() | 销毁自身 |
6.3 玄象项目对 context 的使用
玄象项目当前仅在onCreate中通过context.getApplicationContext()设置颜色模式。未来在 GPS 风水、AI 拍照风水等功能中,将更频繁地使用context.requestPermissionsFromUser()动态申请权限。
七、单 Ability vs 多 Ability 决策矩阵
7.1 何时选择单 UIAbility
玄象项目选择单 UIAbility 的场景:
- 统一入口应用:所有功能从首页进入。
- 强关联页面:页面间跳转频繁,需要统一任务栈。
- 共享状态:页面间共享全局状态(如登录态)。
- 资源节约:减少多 Ability 创建的开销。
7.2 何时选择多 UIAbility
适合拆分多 UIAbility 的场景:
| 场景 | 拆分理由 |
|---|---|
| 独立功能入口 | 用户可直接从桌面进入特定功能 |
| 独立任务管理 | 不同功能需要独立任务栈 |
| 跨设备迁移 | 不同功能需要独立迁移 |
| 权限隔离 | 不同功能需要不同权限集 |
7.3 玄象项目的未来 Ability 拆分设想
玄象项目若未来推出以下功能,应考虑拆分多 UIAbility:
LuopanAbility:独立罗盘功能,用户从桌面直接进入罗盘。WidgetAbility:桌面卡片服务,提供每日宜忌卡片。AssistantAbility:AI 助手独立任务,便于多窗口协同。
提示:Ability 拆分是架构演进的核心议题。玄象项目当前阶段保持单 UIAbility 是合理决策,未来扩展时再按需拆分。
八、EntryAbility 与 EntryBackupAbility 的协同
8.1 协同关系图
[应用启动] ↓ EntryAbility.onCreate() ↓ EntryAbility.onWindowStageCreate() ↓ loadContent('pages/Index') ↓ [SplashPage 3 秒后] → [HomePage 渲染] ↓ [用户使用应用] ↓ [系统触发云备份] ↓ EntryBackupAbility.onBackup() ↓ [系统触发云恢复] ↓ EntryBackupAbility.onRestore()8.2 数据备份范围
玄象项目未来可在onBackup中备份以下数据:
- 用户偏好:主题色、字体大小、提醒开关。
- 历史记录:八字命盘、起卦历史、AI 对话记录。
- 会员信息:会员等级、到期时间、购买记录。
8.3 版本迁移处理
onRestore(bundleVersion)接收BundleVersion参数,玄象项目可在此处理版本迁移:
async onRestore(bundleVersion: BundleVersion) { if (bundleVersion.versionCode < 1000002) { // 旧版本数据迁移逻辑 await this.migrateOldData(); } await Promise.resolve(); }总结
本篇以玄象项目EntryAbility与EntryBackupAbility为蓝本,深入剖析了 HarmonyOS 应用 Ability 设计的取舍决策:单 UIAbility 的优势、EntryAbility 生命周期、EntryBackupAbility 备份扩展能力,以及未来多 Ability 拆分的设想。掌握这些决策框架,能让您在面对不同业务场景时做出合理的 Ability 设计。
下一篇:《07 · code-linter.json5 配置:ArkTS 严格模式下的代码规范》,将带您深入玄象项目的代码静态检查体系。
如果篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!
相关资源:
- HarmonyOS 官方文档:UIAbility 组件
- HarmonyOS 官方文档:BackupExtensionAbility
- HarmonyOS 官方文档:Want
- HarmonyOS 官方文档:Context 上下文
- 开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net