HarmonyOS开发实战:小分享-App项目架构全景解析
前言
HarmonyOS(鸿蒙)作为华为自主研发的分布式操作系统,正在以惊人的速度占领市场。本文将基于一个真实的鸿蒙原生应用「小分享」,从项目架构的全景入手,建立对整个工程的认知。小分享是一款支持文字、图片、链接分享的工具类应用,使用了 HarmonyOS 最新的ArkTS 声明式开发范式和Stage 模型。
本系列共 100 篇文章,将从零到一拆解小分享 App 的实现过程,涵盖组件、界面编写、状态管理、系统能力集成、性能优化、测试与发布全链路。
一、HarmonyOS 开发范式演进
1.1 FA 模型与 Stage 模型对比
HarmonyOS 应用开发经历了两代模型演进,开发者必须清楚两者的差异:
| 对比维度 | FA 模型(旧) | Stage 模型(新) |
|---|---|---|
| Ability 类型 | PageAbility / ServiceAbility / DataAbility | UIAbility / ExtensionAbility |
| 配置文件 | config.json | module.json5 |
| 开发语言 | Java / JavaScript | ArkTS / C++ |
| UI 范式 | 基于XML / JavaScript | 基于ArkTS声明式 |
| 生命周期 | 复杂多状态 | 简化清晰 |
| 推荐场景 | 历史遗留项目 | 新项目首选 |
1.2 Stage 模型核心组件
Stage 模型主要包含以下核心组件:
- UIAbility:承载 UI 的核心组件,负责窗口管理与生命周期调度
- ExtensionAbility:扩展能力,如备份、卡片、输入法等
- WindowStage:窗口舞台,承载所有 UI 内容
- AbilityLoader:Ability 加载器,负责实例化
- Context:上下文对象,提供系统能力访问入口
二、小分享 App 项目目录结构
打开工程根目录xiaofenxiang_ohos_app,可以看到如下典型结构:
xiaofenxiang_ohos_app/ ├── AppScope/ # 应用级配置 │ ├── app.json5 # 应用全局配置 │ └── resources/ # 应用级资源 ├── entry/ # 主模块 │ └── src/ │ ├── main/ │ │ ├── ets/ # ArkTS 源码 │ │ │ ├── common/ # 公共类型定义 │ │ │ ├── components/ # 自定义组件 │ │ │ ├── entryability/ # 入口 Ability │ │ │ └── pages/ # 页面 │ │ ├── module.json5 # 模块配置 │ │ └── resources/ # 模块资源 │ ├── mock/ # Mock 数据 │ └── ohosTest/ # 测试代码 ├── oh-package.json5 # 工程级依赖配置 └── build-profile.json5 # 构建配置这种「AppScope + entry + 多 HSP/HAR」的结构是 HarmonyOS Stage 模型下的标准工程组织方式。详细工程目录说明可参考 HarmonyOS 官方工程结构文档。
三、应用级配置 AppScope/app.json5
3.1 完整配置文件
小分享 App 的应用级配置如下:
{ "app": { "bundleName": "com.shaohushuo.myapplication", "vendor": "example", "versionCode": 1000000, "versionName": "1.0.0", "icon": "$media:layered_image", "label": "$string:app_name" } }3.2 字段含义解析
各字段含义如下表所示:
| 字段 | 类型 | 作用说明 |
|---|---|---|
bundleName | string | 应用唯一标识,上架与签名都依赖它 |
vendor | string | 应用开发商名称或公司名 |
versionCode | int | 版本号数字编码,用于系统判断升级 |
versionName | string | 版本号显示名称,展示给用户 |
icon | string | 应用图标,使用$media:xxx引用 |
label | string | 应用名称,使用$string:xxx引用 |
3.3 bundleName 命名规范
bundleName一旦上架就不能修改,否则会被视为新应用。规划时务必谨慎:
推荐格式:com.<公司反向域名>.<产品名> 命名约束:仅允许小写字母、数字、点号 长度限制:7 ~ 128 字符举几个实际例子:
com.shaohushuo.myapplication(小分享 App)com.huawei.hmos.maps(华为地图)com.tencent.mm(微信)
四、模块级配置 entry/src/main/module.json5
4.1 完整配置示例
{ "module": { "name": "entry", "type": "entry", "description": "$string:module_desc", "mainElement": "EntryAbility", "deviceTypes": ["phone"], "deliveryWithInstall": true, "installationFree": false, "pages": "$profile:main_pages", "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" } ] } ] } }4.2 关键字段说明
模块级配置字段较多,重点关注以下几个:
name:模块名,工程内唯一type:模块类型,取值entry/feature/sharedmainElement:指定启动时加载的 Ability,本工程为EntryAbilitypages:指向resources/base/profile/main_pages.json,是 ArkUI 路由白名单abilities:当前模块的 Ability 列表extensionAbilities:扩展 Ability 列表,例如备份扩展
提示:
mainElement的值必须与abilities数组中某一项的name完全一致,否则会启动失败。
五、入口 Ability 实现分析
5.1 EntryAbility.ets 完整代码
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: %{public}s', JSON.stringify(err)); return; } hilog.info(DOMAIN, 'testTag', '%{public}s', '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'); } }5.2 Ability 生命周期回调
Ability 提供了 6 个核心生命周期回调,开发者按需重写:
onCreate:Ability 实例创建时调用,用于初始化全局资源onDestroy:Ability 实例销毁时调用,用于释放资源onWindowStageCreate:窗口舞台创建时调用,是加载首个页面的时机onWindowStageDestroy:窗口舞台销毁时调用,用于释放 UI 资源onForeground:Ability 切到前台时调用,可恢复动画、刷新数据onBackground:Ability 切到后台时调用,可暂停耗时任务、释放内存
5.3 onCreate 中的颜色模式初始化
onCreate中调用setColorMode让颜色模式跟随系统,用户在系统设置里切换深色模式,App 会自动响应:
this.context.getApplicationContext().setColorMode( ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET );ConfigurationConstant.ColorMode的三个取值如下:
COLOR_MODE_NOT_SET:未设置,跟随系统COLOR_MODE_DARK:强制深色COLOR_MODE_LIGHT:强制浅色
六、页面注册与路由分发
6.1 main_pages.json 路由表
resources/base/profile/main_pages.json列出了所有可访问的页面,是 ArkUI 路由的「白名单」:
{ "src": [ "pages/Index", "pages/SplashPage", "pages/HomePage", "pages/CreateSelectPage", "pages/TextEditPage", "pages/PreviewPage", "pages/TemplateSelectPage", "pages/ImageEditPage", "pages/LinkEditPage", "pages/SharePreviewPage", "pages/FavoritesPage", "pages/ProfilePage", "pages/DiscoverPage", "pages/TemplateDetailPage", "pages/MoreFunctionsPage", "pages/SettingsPage" ] }6.2 入口页路由分发
入口页pages/Index.ets并不展示任何业务内容,只做一次路由跳转:
import router from '@ohos.router'; @Entry @Component struct Index { aboutToAppear(): void { router.replaceUrl({ url: 'pages/SplashPage' }); } build() { Column() { Text('小分享') .fontSize(20) .fontWeight(FontWeight.Bold) .fontColor('#1A1A1A') } .width('100%') .height('100%') .justifyContent(FlexAlign.Center) .alignItems(HorizontalAlign.Center) .backgroundColor(Color.White) } }这种「空入口 + 重定向」的方式便于后续把启动逻辑(埋点、版本检查、登录态恢复)统一收敛到EntryAbility与Index中。
七、整体启动流程架构图
小分享 App 的启动流程可以概括为以下链路:
EntryAbility (Stage 模型入口) │ └─ loadContent(pages/Index) │ └─ replaceUrl(pages/SplashPage) │ └─ setTimeout 2s │ └─ replaceUrl(pages/HomePage) │ └─ BottomTabBar (5 Tab) ├─ HomePage ├─ DiscoverPage ├─ CreateSelectPage (+) ├─ FavoritesPage └─ ProfilePage提示:这种「入口重定向」模式在大型应用中非常常见,例如启动时检查登录态,未登录则重定向到登录页。
八、关键技术点回顾
8.1 Stage 模型核心三件套
Stage 模型开发的三个核心要素:
- UIAbility:承载 UI 与生命周期调度
- WindowStage:窗口舞台,管理 UI 渲染目标
- module.json5:模块级配置文件
8.2 ArkTS 声明式 UI 范式
小分享 App 使用 ArkTS 声明式 UI 范式,其核心装饰器如下:
| 装饰器 | 作用 | 使用场景 |
|---|---|---|
@Entry | 标记入口组件 | 每个页面的根组件 |
@Component | 声明自定义组件 | 可复用的 UI 单元 |
@State | 组件内状态 | 需要驱动 UI 刷新的数据 |
@Prop | 单向同步 | 父组件传给子组件的数据 |
@Builder | 构建 UI 片段 | 可复用的 UI 块 |
@Watch | 监听状态变化 | 状态变化时触发副作用 |
8.3 路由 API 对比
HarmonyOS 提供三种路由方式:
// 1. router 路由(小分享 App 当前使用) router.pushUrl({ url: 'pages/HomePage' }); router.replaceUrl({ url: 'pages/HomePage' }); router.back(); // 2. Navigation 组件(HarmonyOS 推荐方案) const navStack = new NavPathStack(); navStack.pushPath({ name: 'HomePage' }); navStack.pop(); // 3. Tabs 组件(底部 Tab 切换) Tabs() { TabContent() { HomePage() } TabContent() { DiscoverPage() } }详细的路由 API 说明可参考 HarmonyOS Router 官方文档。
九、本篇核心知识点
9.1 工程组织规范
小分享 App 的工程组织遵循以下规范:
- 应用级配置统一放在
AppScope - 主模块放在
entry - 公共类型定义放在
common/interfaces.ets - 自定义组件放在
components/ - 页面放在
pages/
9.2 启动流程要点
启动流程要点总结如下:
EntryAbility是入口,负责窗口挂载pages/Index是路由分发节点,重定向到启动页main_pages.json统一管理页面路由表- 启动逻辑(埋点、版本检查、登录态恢复)建议收敛到
EntryAbility与Index
总结
本文从全景视角拆解了小分享 App 的项目架构,涵盖了Stage 模型、UIAbility 生命周期、应用级与模块级配置、页面注册与路由分发等核心知识点。掌握这些基础架构对于后续深入开发至关重要。下一篇我们将深入EntryAbility的生命周期,看看onCreate/onWindowStageCreate/onForeground/onBackground之间的时序关系,以及如何优雅地处理应用的前后台切换。
相关资源
HarmonyOS 官方文档:HarmonyOS Developer
ArkTS 语法指南:ArkTS Introduction
Stage 模型开发指南:Stage Model Overview
开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
HarmonyOS GitHub 镜像:HarmonyOS Samples
module.json5 配置参考:Module Configuration
app.json5 配置参考:App Configuration
如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!
如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!
