【鸿蒙原生应用开发实战】第一篇:从零搭建“萌宠日记“项目——Stage模型与工程架构解析

【鸿蒙原生应用开发实战】第一篇:从零搭建"萌宠日记"项目------Stage模型与工程架构解析

哈喽大家好,我是AtomCode。最近在搞一个鸿蒙原生应用"萌宠日记",一个宠物健康管理+日常记录的小工具。本文是系列第一篇,带你从新建项目开始,一步步理解鸿蒙Stage模型的工程架构。


一、项目背景与功能概览

"萌宠日记"是一个面向养宠人群的轻量级管理工具,核心功能包括:

模块 功能说明 页面
首页概览 宠物卡片切换、快捷入口、动态信息流 Index.ets
添加宠物 表单录入宠物信息(类型/名字/品种/性别等) AddPetPage.ets
宠物详情 健康档案、体重趋势图表、疫苗接种记录 PetDetailPage.ets
萌宠相册 网格/列表双模式切换、按宠物筛选照片 AlbumPage.ets
提醒管理 疫苗/驱虫/美容提醒、今日待办、已完成归档 ReminderPage.ets

技术栈:ArkTS + Stage模型 + API 23 (HarmonyOS 6.1)


二、项目初始化与DevEco Studio配置

2.1 创建项目

打开DevEco Studio,选择 File → New → Create Project

  • Application Name: 萌宠日记
  • Bundle Name : com.example.petdiary
  • Project Type: Application
  • Compile SDK: API 23 (HarmonyOS 6.1+)
  • Model: Stage
  • Language: ArkTS

注意:API 23 对应的是 HarmonyOS 6.1,用的是 Stage 模型而非 FA 模型。Stage 模型是鸿蒙主推的元程序框架,和 FA 模型最大的区别是:Ability 和 UI 分离,支持多实例、组件化、更好的生命周期管理。

2.2 工程目录结构

创建完成后,项目结构如下:

复制代码
MyApplication/
├── AppScope/                        # 全局应用配置
│   ├── app.json5                    # 应用级配置(bundleName, version等)
│   └── resources/
│       └── base/element/string.json # 全局字符串(app_name)
├── entry/                           # 应用模块
│   ├── src/main/
│   │   ├── ets/
│   │   │   ├── entryability/        # Ability入口
│   │   │   └── pages/               # 页面目录(业务代码)
│   │   ├── module.json5             # 模块配置
│   │   └── resources/               # 资源文件(颜色/字号/字符串)
│   ├── build-profile.json5          # 模块级构建配置
│   └── oh-package.json5             # OHPM依赖管理
├── build-profile.json5              # 项目级构建配置
├── hvigor/                          # 构建工具配置
└── oh_modules/                      # 依赖包
关键文件解读

AppScope/app.json5 ------ 应用的身份证:

json 复制代码
{
  "app": {
    "bundleName": "com.example.myapplication",
    "vendor": "example",
    "versionCode": 1000000,
    "versionName": "1.0.0",
    "icon": "$media:layered_image",
    "label": "$string:app_name"
  }
}

$string:app_name 引用的是 AppScope/resources/base/element/string.json 中定义的 app_name

json 复制代码
{ "name": "app_name", "value": "萌宠日记" }

⚠️ 踩坑:app_name 只能在 AppScope 中定义一次。如果在 entry 模块里也定义同名的 app_name,编译时会报冲突。

build-profile.json5 ------ SDK版本控制:

json 复制代码
{
  "products": [{
    "name": "default",
    "targetSdkVersion": "6.1.1(24)",
    "compatibleSdkVersion": "6.1.0(23)",
    "runtimeOS": "HarmonyOS"
  }]
}

compatibleSdkVersion: 23 表示最低兼容 API 23,targetSdkVersion: 24 表示目标 SDK 版本。


三、Stage模型的核心概念

3.1 Ability与UI分离

Stage 模型下,Ability 是应用入口,负责生命周期管理;UI 由页面组件独立完成。

看我们的 EntryAbility.ets

typescript 复制代码
import { UIAbility, AbilityConstant, Want } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';

export default class EntryAbility extends UIAbility {
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    // Ability创建时的初始化逻辑
    this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);
  }

  onWindowStageCreate(windowStage: window.WindowStage): void {
    // 加载首页
    windowStage.loadContent('pages/Index', (err) => {
      if (err.code) {
        hilog.error(0x0000, 'testTag', 'Failed to load content: %{public}s', JSON.stringify(err));
      }
    });
  }
}

生命周期顺序:onCreate → onWindowStageCreate → onForeground

注意:@kit.AbilityKit 是 API 23+ 的模块导入写法。如果你在 API 23 以下,需要用 @ohos.ability.abilityLifecycleCallback

3.2 页面路由注册

所有页面必须在 main_pages.json 中注册,否则跳转时会找不到页面:

json 复制代码
{
  "src": [
    "pages/Index",
    "pages/AddPetPage",
    "pages/PetDetailPage",
    "pages/AlbumPage",
    "pages/ReminderPage"
  ]
}

module.json5 中通过 "pages": "$profile:main_pages" 引用该配置文件。

3.3 路由跳转与参数传递

我们使用 @ohos.router 进行页面导航:

typescript 复制代码
import router from '@ohos.router';

// 跳转到详情页,携带参数
router.pushUrl({
  url: 'pages/PetDetailPage',
  params: { petId: 1 }
});

// 接收参数
const params: Record<string, Object> = router.getParams() as Record<string, Object>;
const petId: number = params['petId'] as number;

// 返回上一页
router.back();
关于 @ohos.router vs @kit.AbilityKit

这里有个重要的兼容性问题需要说明:

在 API 23 下,router 模块从 @ohos.router 导入。有些同学在查阅官方文档时可能会看到 @kit.AbilityKit 的写法,但 API 23 的 @kit.AbilityKit 并不导出 router。所以一定要用:

typescript 复制代码
import router from '@ohos.router';  // ✅ 正确
// import router from '@kit.AbilityKit';  // ❌ API 23 不适用

四、资源管理体系

鸿蒙的资源管理通过 $r$media 等语法糖实现。我们项目中用到了三类资源:

4.1 颜色资源 color.json

json 复制代码
{
  "color": [
    { "name": "start_window_background", "value": "#FFFFFF" },
    { "name": "primary_color", "value": "#FF6B35" },
    { "name": "background_color", "value": "#F5F5F5" },
    { "name": "header_bg", "value": "#1A1A2E" }
  ]
}

使用方式:$r('app.color.primary_color') 或直接在代码中用字符串 '#FF6B35'

4.2 字号资源 float.json

json 复制代码
{
  "float": [
    { "name": "title_font_size", "value": "22fp" },
    { "name": "subtitle_font_size", "value": "16fp" },
    { "name": "card_radius", "value": "12vp" },
    { "name": "list_item_height", "value": "80vp" }
  ]
}

fp 是字体像素(Font Pixel),会跟随系统字体大小缩放;vp 是虚拟像素(Virtual Pixel),适配不同屏幕密度。

4.3 为什么不把所有样式写在资源文件里?

很多人刚接触鸿蒙开发会问:样式写在代码里还是资源文件里?

我的实践原则是:

  • 全局统一Token → 资源文件(主题色、主字体、圆角标准)
  • 页面局部样式 → 代码内直接写(方便调试、所见即所得)

我们的项目里颜色直接在代码中写字符串,是因为每个页面有自己的配色风格,抽到资源文件反而增加维护成本。


五、构建与运行

5.1 命令行构建

DevEco Studio 提供了图形化构建,但我们也可以命令行构建:

bash 复制代码
node "D:\DevEco Studio\tools\node\node.exe" "D:\DevEco Studio\tools\hvigor\bin\hvigorw.js" \
  --mode module \
  -p module=entry@default \
  -p product=default \
  -p requiredDeviceType=phone \
  assembleHap \
  --analyze=normal \
  --parallel \
  --incremental \
  --daemon

参数说明:

  • --mode module:模块级构建
  • -p module=entry@default:构建 entry 模块的 default 产品
  • assembleHap:打包成 HAP 文件
  • --incremental:增量编译,二次构建更快
  • --daemon:守护进程模式

5.2 真机调试

鸿蒙应用调试推荐使用 远程模拟器真机

  1. 在 DevEco Studio 中登录华为账号
  2. 连接设备或启动模拟器
  3. 点击运行按钮(▶️)

六、踩坑总结

这一篇先列几个新手必踩的坑:

问题 表现 解决方案
app_name 重复定义 编译报 resource conflict 只在 AppScope 中定义一次
router 导入路径错误 编译报找不到模块 @ohos.router 而非 @kit.AbilityKit
页面跳转报 404 router.pushUrl 找不到页面 检查 main_pages.json 中是否注册
对象字面量类型错误 arkts-no-untyped-obj-literals 为对象字面量显式声明类型/提取为类型变量

七、下篇预告

下一篇我们开始写代码!重点分析 首页(Index.ets) 的实现:

  • 宠物卡片横向滚动选择器
  • 快速操作功能区(4个核心入口)
  • 萌宠动态信息流(ForEach 渲染、Emoji 搭配)

咱们下篇见!🚀


SDK版本 : API 23 (HarmonyOS 6.1) | 框架: Stage模型 + ArkTS

相关推荐
charlee442 小时前
Unity项目适配华为鸿蒙系统的原生库加载问题排查与解决
华为·unity3d·鸿蒙·cmake·c/c++·relro
狼哥16862 小时前
《新闻资讯》二、公共能力层模块实现指南
ui·华为·harmonyos
Ww.xh2 小时前
启用Hypervisor解决模拟器问题
华为·harmonyos
金启攻3 小时前
【鸿蒙原生应用实战】第二篇:装备库页面——分类筛选与数据驱动UI
harmonyos
木咺吟5 小时前
鸿蒙原生应用实战(四):愿望单与个人统计 — 数据聚合与可视化
华为·harmonyos
木咺吟6 小时前
鸿蒙原生应用实战(二):游戏库列表与筛选排序 — 卡片式UI设计
harmonyos
互联网散修7 小时前
鸿蒙实战:从零实现自定义相机(下)——填平预览拉伸、比例错乱、缩略图消失的六大坑
数码相机·华为·harmonyos
风华圆舞7 小时前
鸿蒙 + Flutter 下 AI 助手为什么要支持流式输出
人工智能·flutter·harmonyos
金启攻8 小时前
【鸿蒙原生应用实战】第四篇:打包清单——勾选交互、进度计算与实用工具
harmonyos