鸿蒙原生应用实战(一):从零搭建快递追踪App------项目初始化与工程架构详解
本文是「鸿蒙原生应用实战」系列第一篇,带你从零开始,使用 DevEco Studio 搭建一个完整的快递追踪 App,涵盖 Stage 模型、工程配置、资源管理和路由注册等核心内容。
一、前言
HarmonyOS(鸿蒙操作系统)自诞生以来,其原生应用开发框架不断演进。目前主流的开发模式是 Stage 模型 + ArkTS 语言,相比过去的 FA 模型,Stage 模型在组件化、生命周期管理、任务调度等方面更加成熟。
本系列将以一个 快递追踪 App (PackageTracker)为实战项目,记录完整的开发过程。第一篇聚焦于 项目初始化与工程架构。
项目概览
应用名称 :快递追踪
包名 :com.packagetracker.app
最低兼容 API :23(HarmonyOS 6.1.0)
目标 API :24(HarmonyOS 6.1.1)
框架 :Stage 模型 + ArkTS
IDE:DevEco Studio 6.x
快递追踪 App 的核心功能:
- 首页展示包裹列表,区分运输中/已签收/异常三种状态
- 添加快递单号,选择快递公司,添加备注
- 查看物流轨迹时间线
- 历史记录查询
- 搜索与筛选包裹
- 快递公司管理(收藏常用公司)
- 数据统计(月度趋势、公司分布)
- 个人中心(通知设置、统计概览)
二、创建项目
2.1 使用 DevEco Studio 新建项目
打开 DevEco Studio,点击 Create Project,选择:
- 模板:Empty Ability(Stage 模型)
- 项目名:MyApplication
- 包名:com.packagetracker.app
- 兼容 SDK:选择 API 23
- 语言:ArkTS
2.2 初始工程结构
创建完成后,工程目录结构如下:
MyApplication/
├── AppScope/ ← 全局应用配置
│ ├── app.json5 ← 应用级配置
│ └── resources/ ← 全局资源
│ └── base/element/string.json
├── entry/ ← 主模块(entry type)
│ ├── src/main/
│ │ ├── ets/ ← ArkTS 源码
│ │ │ ├── entryability/ ← Ability 入口
│ │ │ └── pages/ ← 页面文件
│ │ ├── resources/ ← 模块级资源
│ │ └── module.json5 ← 模块配置
│ ├── build-profile.json5 ← 模块构建配置
│ └── oh-package.json5 ← OHPM 依赖
├── build-profile.json5 ← 顶层构建配置
├── hvigor/ ← 构建工具配置
└── oh-package.json5 ← 顶层依赖
三、Stage 模型核心概念
Stage 模型是 HarmonyOS 从 API 9 开始主推的 Ability 架构,有三个核心概念:
3.1 UIAbility
每个应用有一个或多个 UIAbility,是应用与系统交互的入口。我们的 App 有一个 EntryAbility:
typescript
// entryability/EntryAbility.ets
import { UIAbility, AbilityConstant, Want } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';
export default class EntryAbility extends UIAbility {
onWindowStageCreate(windowStage: window.WindowStage): void {
windowStage.loadContent('pages/Index', (err) => {
if (err.code) {
hilog.error(0x0000, 'testTag', 'Failed: %{public}s', JSON.stringify(err));
}
});
}
}
关键点:
onWindowStageCreate是加载 UI 的入口loadContent指定首页页面路径'pages/Index'- Ability 生命周期:
onCreate→onWindowStageCreate→onForeground→onBackground→onWindowStageDestroy→onDestroy
3.2 module.json5
每个模块的配置文件,类似于 Android 的 AndroidManifest.xml:
json5
{
"module": {
"name": "entry",
"type": "entry", // entry: 主模块, feature: 特性模块
"mainElement": "EntryAbility",
"deviceTypes": ["phone"],
"pages": "$profile:main_pages", // 引用路由配置
"abilities": [
{
"name": "EntryAbility",
"srcEntry": "./ets/entryability/EntryAbility.ets",
"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"]
}
]
}
]
}
}
这里有两个重要细节:
- startWindowBackground 指向
$color:start_window_background,在color.json中定义为白色#FFFFFF,确保启动时不会闪黑屏 - skills 声明了这个 Ability 响应 Home 事件,即桌面图标点击进入
3.3 页面路由
在 resources/base/profile/main_pages.json 中注册所有页面:
json
{
"src": [
"pages/Index",
"pages/AddPackagePage",
"pages/TrackDetailPage",
"pages/HistoryPage",
"pages/ProfilePage",
"pages/SearchPage",
"pages/CompanyManagePage",
"pages/PackageStatsPage"
]
}
每个页面对应 ets/pages/ 下同名文件,注册顺序不重要,但必须全部列出,否则跳转时会报错。
四、构建配置详解
4.1 顶层 build-profile.json5
json5
{
"app": {
"products": [
{
"name": "default",
"signingConfig": "default",
"targetSdkVersion": "6.1.1(24)",
"compatibleSdkVersion": "6.1.0(23)",
"runtimeOS": "HarmonyOS"
}
],
"buildModeSet": [
{ "name": "debug" },
{ "name": "release" }
]
}
}
- compatibleSdkVersion: 最低兼容版本(向下兼容到此版本)
- targetSdkVersion: 目标版本(用此版本的 API 编译)
- 这里 API 23 ≈ HarmonyOS 6.1.0,API 24 ≈ HarmonyOS 6.1.1
4.2 AppScope/app.json5
json5
{
"app": {
"bundleName": "com.packagetracker.app",
"vendor": "atomcode",
"versionCode": 1000000,
"versionName": "1.0.0",
"icon": "$media:layered_image",
"label": "$string:app_name"
}
}
- bundleName:包名,全局唯一,发布后不可更改
- versionCode:版本号整数,用于版本比较
- versionName:展示给用户的版本名
4.3 API 23 下路由导入的注意事项
在 API 23 中,router 从 @ohos.router 导入,而非 @kit.AbilityKit:
typescript
// ✅ 正确(API 23)
import router from '@ohos.router';
// ❌ 错误(API 23 不导出此模块)
import router from '@kit.AbilityKit';
页面跳转标准写法:
typescript
interface RouteOpt {
url: string;
params?: Object;
}
// 跳转
let opt: RouteOpt = { url: 'pages/SearchPage' };
router.pushUrl(opt);
// 带参数跳转
let params = { packageData: item };
let opt: RouteOpt = { url: 'pages/TrackDetailPage', params: params };
router.pushUrl(opt);
// 返回上一页
router.back();
// 接收参数
const params = router.getParams() as Record<string, Object>;
if (params && params['packageData']) {
this.packageData = params['packageData'] as PackageItem;
}
五、资源管理体系
鸿蒙的资源系统通过 $r() 引用,支持根据设备配置(密度、语言、深色模式等)自动切换。
5.1 string.json --- 字符串资源
json
{
"string": [
{ "name": "title_home", "value": "我的包裹" },
{ "name": "title_add_package", "value": "添加包裹" },
{ "name": "btn_save", "value": "保存" },
{ "name": "status_transit", "value": "运输中" },
{ "name": "status_delivered", "value": "已签收" },
{ "name": "status_exception", "value": "异常" }
]
}
5.2 color.json --- 颜色资源
json
{
"color": [
{ "name": "primary", "value": "#FF4A90D9" },
{ "name": "background", "value": "#FFF5F5F5" },
{ "name": "card_bg", "value": "#FFFFFF" },
{ "name": "text_primary", "value": "#FF333333" },
{ "name": "text_secondary", "value": "#FF666666" },
{ "name": "text_hint", "value": "#FF999999" },
{ "name": "divider", "value": "#FFE0E0E0" },
{ "name": "status_transit", "value": "#FFFF8C00" },
{ "name": "status_delivered", "value": "#FF4CAF50" },
{ "name": "status_exception", "value": "#FFF44336" },
{ "name": "rating_star", "value": "#FFFFC107" }
]
}
5.3 float.json --- 字号与尺寸资源
json
{
"float": [
{ "name": "page_title_font_size", "value": "22fp" },
{ "name": "body_font_size", "value": "16fp" },
{ "name": "small_font_size", "value": "13fp" },
{ "name": "badge_font_size", "value": "11fp" },
{ "name": "card_corner_radius", "value": "12vp" },
{ "name": "btn_corner_radius", "value": "8vp" },
{ "name": "padding_medium", "value": "16vp" }
]
}
fp(Font Pixel)是鸿蒙的字号单位,自带字体缩放适配;vp(Virtual Pixel)是虚拟像素,与 dp 类似。
5.4 在 ArkTS 中使用资源
typescript
Text($r('app.string.title_home'))
.fontSize($r('app.float.page_title_font_size'))
.fontColor($r('app.color.text_primary'))
.backgroundColor($r('app.color.primary'))
重要约定 :app_name 只在 AppScope 的 string.json 中定义一次,不能在 entry 模块中重复定义,否则会冲突。
5.5 深色模式适配
在 entry/src/main/resources/dark/element/color.json 中可以配置深色模式下的颜色值,系统会根据系统主题自动切换。
六、底层构建系统:Hvigor
鸿蒙使用自研的 Hvigor 构建系统(类似于 Gradle),构建命令如下:
bash
hvigorw --mode module -p module=entry@default -p product=default \
-p requiredDeviceType=phone assembleHap --analyze=normal --parallel --incremental --daemon
常用参数:
--mode module:模块级构建-p module=entry@default:指定模块和 targetassembleHap:打包 HAP 文件--parallel:并行构建--incremental:增量编译--daemon:守护进程模式,加速后续构建

七、小结
本篇我们完成了:
- ✅ 使用 DevEco Studio 创建鸿蒙原生项目
- ✅ 理解 Stage 模型的 UIAbility 生命周期
- ✅ 理解 module.json5 的配置含义
- ✅ 掌握页面路由注册与跳转标准写法
- ✅ 构建配置文件(compatibleSdkVersion / targetSdkVersion)
- ✅ 资源管理体系(string/color/float + $r() 引用)
- ✅ API 23 下 router 从
@ohos.router导入的注意事项
下一篇将进入 首页与列表开发,讲解 List 组件、ForEach 渲染、状态管理、空状态设计等实战内容。
系列索引:
- 第一篇:项目初始化与工程架构(本文)
- 第二篇:首页与列表开发实战
- 第三篇:表单交互与搜索筛选
- 第四篇:物流时间线与历史记录
- 第五篇:数据统计与个人中心