HarmonyOS 第一个工程:Empty Ability 怎么选、目录都是啥(DevEco 26 实测)
环境说明:基于 DevEco Studio 26.0.x 实测整理;工程结构等基础概念适用于 API 12 及以上版本。
构建第一个 HarmonyOS 应用(ArkTS):快速了解工程目录的主要文件,熟悉使用 DevEco Studio 创建应用的全过程,完成一次简单编码和效果验证。
一、新建工程:向导里的选项都是啥
打开 DevEco Studio → Create Project,向导里几个关键选择:
1. 模板选 Empty Ability。 不选带登录、Tab 这类现成模板的原因:那些代码你现在看不懂,出了问题没法改。空模板从最小可运行开始,每一步都是自己写的。

2. 工程名和包名(bundle name)。 命名规则是域名倒序:com.example.myapplication 这种。注意:上架前这个包名要和 AppGallery Connect 后台申请的保持一致,起名时别随便写(上架流程详见《应用上架全流程》)。保存位置延续上篇原则——纯英文路径,不带空格和中文。

3. SDK 版本选择。 向导里会让你选 Compatible SDK(最低兼容版本),三个概念别混:
| 概念 | 作用 | 怎么选 |
|---|---|---|
| Compile SDK | 编译时用的 API 版本 | 不用选,默认最新版本26.0.0 |
| Compatible SDK | 保证能运行的最低版本 | 选择主流6.1.1(24)即可 |
| Target SDK | 测试针对的版本 | 不用选,默认最新版本26.0.0 |
二、工程结构导览:这些目录都是干嘛的
工程建好后长这样(以下基于 DevEco 26.0.x 实际生成的工程整理,已省略 .gitignore 忽略的缓存和构建目录):
MyApplication/
├── AppScope/ # 应用级配置
│ ├── app.json5 # 应用名、图标、版本号、bundleName
│ └── resources/base/ # 应用级资源(桌面图标等)
├── entry/ # 主模块,最终打包成 HAP 跑在设备上
│ ├── src/main/ets/ # ArkTS 代码:entryability(生命周期入口)、
│ │ # entrybackupability(备份恢复)、pages(Index.ets 首页)
│ ├── src/main/resources/ # 模块资源:base(默认)/ dark(深色模式)/ rawfile(原始文件)
│ ├── src/main/module.json5 # 模块配置:有哪些页面、申请了什么权限
│ ├── src/test/ # 单元测试代码
│ ├── src/ohosTest/ # 设备测试代码(跑在真机/模拟器上)
│ ├── src/mock/ # mock 数据目录
│ ├── oh-package.json5 # 模块级依赖声明
│ ├── build-profile.json5 # 模块构建配置
│ ├── hvigorfile.ts # 模块构建脚本入口
│ └── obfuscation-rules.txt # 代码混淆规则(打 Release 包用)
├── hvigor/hvigorfile.ts # 构建体系:hvigor 相当于 HarmonyOS 的 gradle,管编译打包
├── oh-package.json5 # 工程级依赖声明
├── oh-package-lock.json5 # 依赖锁定文件:团队统一版本,避免"我这能跑你那不能跑"
├── build-profile.json5 # 工程构建配置(签名在这里配,上架篇细讲)
└── code-linter.json5 # 代码静态检查规则
把 entry/src/main/ 这一层展开看,里面才是真正的代码和资源目录:
entry/src/main/
├── ets/
│ ├── entryability/ # 生命周期入口:EntryAbility.ets(应用启动、前后台切换)
│ ├── entrybackupability/ # 备份恢复:EntryBackupAbility.ets
│ └── pages/ # 页面:Index.ets 就是首页
├── resources/
│ ├── base/ # 默认资源:element(字符串/颜色)、media(图片)、profile(页面配置)
│ ├── dark/ # 深色模式资源
│ └── rawfile/ # 原始文件(视频、PDF 等,按路径直接读取)
└── module.json5 # 模块配置:有哪些页面、申请了什么权限
这几类配置文件各管什么,一句话记住(工程级和模块级各有一份,职责相同、就近生效):
- oh-package.json5 = 依赖声明,类似 package.json(工程级管整个工程,模块级只管 entry)
- module.json5 = 模块有哪些页面和能力、申请了什么权限
- build-profile.json5 = 怎么编译、用什么签名(上架篇会再回来讲它)
- code-linter.json5 / obfuscation-rules.txt = 代码检查规则和混淆规则,新手期先不用动
三、让页面跑起来:三种方式怎么选
| 方式 | 速度 | 适合场景 | 局限 |
|---|---|---|---|
| 预览器 Preview | 秒开,边改边看 | 调布局、调样式 | 部分 API 和系统能力不支持,行为与真机有差异 |
| 模拟器 | 约等于真机 | 没有华为手机的日常开发 | 吃内存;部分硬件能力没有 |
| 真机 | 最真实 | 最终验证、调硬件能力 | 需要签名(下一篇讲) |
四、第一次改动闭环
目标:把首页文字改成自己的,验证”改代码 → 看到效果”这条链路是通的。
entry/src/main/ets/pages/Index.ets 最简结构长这样:
@Entry
@Component
struct Index {
@State message: string = 'Hello World';
build() {
RelativeContainer() {
Text(this.message)
.id('HelloWorld')
.fontSize($r('app.float.page_text_font_size'))
.fontWeight(FontWeight.Bold)
.alignRules({
center: { anchor: '__container__', align: VerticalAlign.Center },
middle: { anchor: '__container__', align: HorizontalAlign.Center }
})
.onClick(() => {
this.message = 'Welcome';
})
}
.height('100%')
.width('100%')
}
}
改完看效果:保存即可在预览器里刷新。

一个马上养成的好习惯:界面上的文字不要硬编码在代码里,放进 entry/src/main/resources/base/element/string.json:
{
"string": [
{
"name": "hello_text",
"value": "你好,HarmonyOS"
}
]
}
代码里用 $r('app.string.hello_text') 引用。现在看是多此一举,等做多语言(开发栏目会讲)和统一改文案时就知道香了。
五、常见卡点速查
最后留一张速查表。以下都是新手最高频的卡点,遇到按表排查即可:
| 现象 | 排查 |
|---|---|
| 预览器一直 Loading / 白屏 | File → Invalidate Caches 清缓存重启;还不行检查 SDK 是否完整 |
| 运行按钮是灰的 | 没选运行设备,或 SDK 没装全(SDK Manager 里补) |
| sync 报错 / 一直转圈 | 网络问题居多,换网络或配代理;依赖没拉全就重新 sync |
| 改了代码没变化 | 预览器没刷新;或改的不是当前展示的页面 |
| 模拟器启动失败 | 回到《DevEco 安装 6 坑》第 3 条:九成是虚拟化没开 |
小结
至此,基于 ArkTS 的第一个 HarmonyOS 应用已经跑起来了,整个过程比预想顺利。日常建议:只是调 UI,预览器完全够用;涉及 API 调用、手头又没真机,模拟器是不错的选择;真机效果当然最准确——涉及账号、扫码等依赖硬件或认证的能力,目前只有真机能用。
相关阅读:上一步装环境遇到的问题看 DevEco Studio 安装与首次配置:新手最容易踩的 6 个坑;下一步给真机跑起来,见《签名与真机调试》(待发布)。
有收获的话,欢迎把本文分享给其他鸿蒙开发者。发现内容过时或有误?欢迎在评论区指出,我会持续更新。