1. 鸿蒙应用开发环境概述
作为一个从Android转型鸿蒙开发的工程师,第一次打开Deveco Studio创建项目时,那种既熟悉又陌生的感觉至今难忘。鸿蒙的工程结构与Android有着本质区别,它采用了更现代化的模块化设计理念。让我们从一个真实商业项目的角度,彻底拆解鸿蒙App的目录结构。
当前鸿蒙应用开发主要使用ArkTS语言(TypeScript的超集),配合Deveco Studio这个官方IDE。与Android Studio不同,Deveco Studio从项目创建阶段就强制采用分层的模块化结构,这种设计对大型应用非常友好,但对初学者可能造成一定认知门槛。
提示:本文基于HarmonyOS 4.0 SDK和Deveco Studio 3.1版本,不同版本间可能存在细微差异。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 工程根目录解析
当我们通过Deveco Studio新建一个"Empty Ability"项目后,会生成如下核心文件和目录(以实际电商项目"ShopHarmony"为例):
code复制ShopHarmony/
├── .deveco/ # IDE配置目录
├── entry/ # 主模块
├── feature/ # 功能模块目录
│ ├── payment/ # 支付模块
│ └── usercenter/ # 用户中心模块
├── library/ # 公共库目录
│ ├── network/ # 网络请求库
│ └── utils/ # 工具类库
├── build-profile.json5 # 全工程构建配置
├── hvigorfile.ts # 构建脚本
└── README.md
这种结构明显区别于Android的单模块平铺式设计。鸿蒙强制采用多模块化设计,即使最简单的应用也至少包含一个entry模块。在实际项目中,我们通常按功能划分多个feature模块,将公共代码抽离到library中。
3. 主模块(entry)深度拆解
entry模块是应用的入口,其结构如下:
code复制entry/
├── src/
│ ├── main/
│ │ ├── ets/ # ArkTS代码
│ │ │ ├── Application # 应用全局逻辑
│ │ │ ├── MainAbility # 入口Ability
│ │ │ └── pages/ # 页面目录
│ │ │ ├── Index.ets # 首页
│ │ │ └── ...
│ │ ├── resources/ # 资源文件
│ │ │ ├── base/
│ │ │ │ ├── element/ # 字符串等
│ │ │ │ ├── media/ # 图片等
│ │ │ │ └── ...
│ │ │ └── en_US/ # 英文资源
│ │ └── module.json5 # 模块配置
│ └── ohosTest/ # 测试代码
├── build-profile.json5 # 模块构建配置
└── hvigorfile.ts # 模块构建脚本
关键文件解析:
- module.json5:这是模块的核心配置文件,相当于Android的AndroidManifest.xml。但它的结构更加清晰:
json复制{
"module": {
"name": "entry",
"type": "entry",
"description": "$string:module_desc",
"mainElement": "MainAbility",
"abilities": [{
"name": "MainAbility",
"srcEntry": "./ets/MainAbility/MainAbility.ts",
"icon": "$media:icon",
"label": "$string:MainAbility_label",
"startWindowIcon": "$media:icon",
"startWindowBackground": "$color:red"
}]
}
}
- 页面路由机制:鸿蒙使用声明式UI,pages目录下的每个.ets文件自动注册为路由页面。例如Index.ets对应的路由路径即为"/Index"。
4. 功能模块(feature)设计规范
在真实项目中,我们会将不同功能拆分为独立模块。以支付模块为例:
code复制feature/payment/
├── src/
│ ├── main/
│ │ ├── ets/
│ │ │ ├── components/ # 组件
│ │ │ ├── model/ # 数据模型
│ │ │ ├── view/ # 页面
│ │ │ └── PaymentAbility.ts
│ │ ├── resources/
│ │ └── module.json5
└── build-profile.json5
与entry模块不同,feature模块的module.json5中type应设置为"feature":
json复制{
"module": {
"name": "payment",
"type": "feature",
"abilities": [{
"name": "PaymentAbility",
"srcEntry": "./ets/PaymentAbility.ts",
"exported": true // 允许外部调用
}]
}
}
跨模块调用需要使用FeatureAbility:
typescript复制import featureAbility from '@ohos.ability.featureAbility';
featureAbility.startAbility({
bundleName: "com.example.shop",
moduleName: "payment",
abilityName: "PaymentAbility"
});
5. 公共库模块(library)最佳实践
library模块存放被多个模块共享的代码,以网络库为例:
code复制library/network/
├── src/
│ ├── main/
│ │ ├── ets/
│ │ │ ├── HttpManager.ts
│ │ │ └── interceptors/
│ │ └── module.json5
└── build-profile.json5
其module.json5需设置为"har"类型(Harmony Archive):
json复制{
"module": {
"name": "network",
"type": "har"
}
}
其他模块引用时,需要在目标模块的build-profile.json5中添加依赖:
json复制"dependencies": [
{
"har": ":network"
}
]
6. 资源管理机制详解
鸿蒙的资源管理系统比Android更加严格:
-
多分辨率适配:
code复制resources/ ├── base/ │ ├── media/ │ │ ├── icon.png │ │ └── splash.png ├── en_US/ │ ├── media/ │ │ └── icon.png └── zh_CN/ ├── media/ │ └── icon.png -
资源引用方式:
- 代码中:
$r('app.string.app_name') - JSON中:
"$string:app_name"
- 代码中:
-
主题资源:
在base/element/目录下可以定义color.json、theme.json等:json复制// color.json { "color": [ { "name": "primary_color", "value": "#FF6200" } ] }
7. 构建系统与配置文件
鸿蒙使用hvigor作为构建工具(类似Gradle):
-
工程级配置(build-profile.json5):
json复制{ "app": { "signingConfigs": [{ "name": "release", "keystorePath": "signkey.jks", "keyAlias": "shop", "keyPassword": "xxx", "storePassword": "xxx" }], "targets": [{ "name": "default", "runtimeOS": "HarmonyOS" }] } } -
模块级配置(hvigorfile.ts):
typescript复制import { harTask, ohosBuild } from '@ohos/hvigor-ohos-plugin'; ohosBuild.setup((task) => { task.build() })
8. 实际开发中的经验技巧
-
模块划分原则:
- 按功能独立性划分
- 公共代码必须抽离到library
- 高频变更的模块应独立
-
常见问题排查:
- 模块间循环依赖:使用"har"类型库模块作为中间层
- 资源冲突:各模块的resources/base目录下的文件名必须唯一
- 能力(Ability)未导出:确保module.json5中exported设为true
-
性能优化建议:
- 将不常用的功能拆分为按需加载的feature模块
- 使用"atomic"资源类型减少包体积
- 启用代码混淆(在build-profile.json5中配置proguard)
-
调试技巧:
bash复制# 查看模块依赖树 hdc shell bm dump -n <package_name> # 强制刷新资源 hdc shell aa start -b <bundle> -a <ability> -C
经过三个鸿蒙商业项目的实战,我发现这种模块化设计虽然初期学习成本较高,但在团队协作、代码复用和构建速度方面优势明显。特别是当应用需要支持多种设备形态时,合理的模块划分能大幅降低适配工作量。
