HarmonyOS应用《玄象》开发实战:多 Ability 还是单 Ability?EntryAbility 与 EntryBackupAbility 的取舍

阅读时长:约 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
更多推荐


所有评论(0)