HarmonyOS应用<民族图鉴>开发第1篇:开篇——为什么选择鸿蒙原生开发

📖 引言
2019年8月9日,华为在开发者大会上正式发布 HarmonyOS 1.0,彼时鸿蒙还被许多人视为"备胎计划"的应急产物。六年时间,从 1.0 到 7.0,从 IoT 设备到手机、平板、车机、手表、智慧屏全场景覆盖,从兼容安卓到 HarmonyOS NEXT 纯血鸿蒙,鸿蒙走出了一条属于自己的路。
根据 Counterpoint Research 的数据,2025 年 Q1 鸿蒙在中国智能手机市场份额已突破 20%,稳居全球第三大移动操作系统。更重要的是,随着 API 26(HarmonyOS 7)的发布,鸿蒙在智能化(Agent、Skill、视觉AI)、空间化(3DGS、空间音频)、多窗交互(闪控悬浮窗、互动卡片升级)等方向的创新,正在重新定义下一代应用的形态。
本系列文章以「民族图鉴」应用为载体,从零到一完整呈现 HarmonyOS 原生应用开发的全流程。我们不会停留在"怎么做"的层面,更会深入讲解"为什么这么做"——从方舟编译器的原理到 ArkUI 的渲染机制,从分布式软总线的架构到状态管理的设计哲学。读完这 100 篇,你不仅能做出一款精美的民族文化应用,更能建立起对鸿蒙操作系统和应用开发体系的深度理解。
🎯 学习目标
完成本文后,你将能够:
- ✅ 理解 HarmonyOS 的技术架构与设计哲学
- ✅ 掌握方舟编译器(ArkCompiler)的工作原理与性能优势
- ✅ 理解声明式 UI(ArkUI)的渲染机制与状态驱动模型
- ✅ 熟悉「民族图鉴」项目的分层架构与数据流设计
- ✅ 明确 100 篇系列文章的知识体系与学习路径
- ✅ 评估鸿蒙原生开发 vs 跨平台方案的技术选型依据
💡 需求分析
项目背景:为什么做「民族图鉴」
在确定用什么技术做之前,先想清楚做什么、为什么做。「民族图鉴」项目的定位是:
一款系统介绍中国 56 个民族文化的科普类应用,以精美的视觉设计、沉浸式的交互体验、丰富的内容模块,让用户在轻松愉悦中了解各民族的历史、文化、风俗、语言和分布。
之所以选择这个题材,有三层考虑:
1. 内容复杂度适中,技术覆盖全面
- 56 个民族 = 56 条数据,足以测试列表、搜索、分页等功能
- 每个民族包含文字、图片、音频等多种内容形式,覆盖多媒体处理
- 涉及地图、测验、收藏、分享等典型 App 功能模块
- 可以自然地扩展 AI、音乐、3D 等创新功能
2. 文化价值与社会意义
- 民族文化是中华文化的重要组成部分,有传播价值
- 内容正面积极,适合作为教程演示项目
- 可以结合鸿蒙新特性(如 AI 问答、空间音频)打造差异化体验
3. 设计空间大,视觉效果好
- 56 个民族各有特色,封面图、标志色、文化元素丰富
- 适合展示精美的 UI 设计和动画效果
- 容易做出"看起来很专业"的作品
功能模块全景
| 模块 | 子功能 | 技术挑战 |
|---|---|---|
| 首页 | 搜索、冷知识、精选民族、快捷入口、热门推荐 | Tabs 嵌套滚动、横向滑动、性能优化 |
| 民族百科 | 列表页、详情页、56 民族完整信息 | 列表懒加载、图片缓存、页面转场 |
| 地图分布 | 地理分布可视化、民族标记点 | 地图 SDK 集成、自定义标记、区域着色 |
| 知识测验 | 答题系统、错题本、答题记录 | 状态管理、计分逻辑、数据持久化 |
| 个人中心 | 收藏、历史、图鉴、设置 | 存储服务、状态同步、用户偏好 |
| 音乐馆 | 民族音乐、悬浮播放、空间音频 | 媒体服务、后台播放、音频特效 |
| AI 助手 | 智能问答、语音交互 | Agent 智能体、NLP、TTS |
| 图片工具 | 超分、文搜图、AI 识别 | 端侧 AI、视觉模型、图像处理 |
技术选型深度对比
| 维度 | 鸿蒙原生(ArkTS) | Flutter | React Native | 小程序 |
|---|---|---|---|---|
| 性能 | ⭐⭐⭐⭐⭐ 原生渲染,方舟编译器 AOT | ⭐⭐⭐⭐ Skia 自绘,接近原生 | ⭐⭐⭐ JS 桥接,有损耗 | ⭐⭐⭐ WebView/双线程 |
| 系统能力 | ⭐⭐⭐⭐⭐ 完整 Kit,深度集成 | ⭐⭐⭐ 需插件支持 | ⭐⭐⭐ 需原生模块 | ⭐⭐⭐ 受限的 API |
| 分布式能力 | ⭐⭐⭐⭐⭐ 原生支持,软总线 | ⭐⭐ 需自行实现 | ⭐⭐ 需自行实现 | ⭐ 基本无 |
| AI 能力 | ⭐⭐⭐⭐⭐ 端侧 AI,系统级 | ⭐⭐ 需第三方 | ⭐⭐ 需第三方 | ⭐⭐ 云端调用 |
| 多端部署 | ⭐⭐⭐⭐ 鸿蒙生态各设备 | ⭐⭐⭐⭐⭐ 全平台 | ⭐⭐⭐⭐ iOS+Android | ⭐⭐ 微信生态 |
| 开发效率 | ⭐⭐⭐⭐ 声明式 UI,简洁 | ⭐⭐⭐⭐ Dart 简洁 | ⭐⭐⭐⭐ React 生态 | ⭐⭐⭐⭐ 上手快 |
| 生态成熟度 | ⭐⭐⭐ 快速增长中 | ⭐⭐⭐⭐⭐ 非常成熟 | ⭐⭐⭐⭐⭐ 非常成熟 | ⭐⭐⭐⭐⭐ 非常成熟 |
| 学习曲线 | ⭐⭐⭐ 有 TS 基础很快 | ⭐⭐⭐ Dart 需学习 | ⭐⭐⭐ 有 React 基础很快 | ⭐⭐ 最简单 |
选型结论:
- 如果你的目标是鸿蒙生态,追求极致性能和深度系统能力,选原生
- 如果你的目标是多端覆盖,团队有前端/Flutter 背景,选跨平台
- 本系列选择原生开发,因为我们要深入探索鸿蒙 7 的全部能力
🛠️ 核心实现
步骤1:HarmonyOS 技术架构深度解析
要理解鸿蒙应用开发,首先要理解鸿蒙系统的技术架构。HarmonyOS 采用分层架构,从下至上分为四层:
┌─────────────────────────────────────────────────────┐
│ 应用层 (Applications) │
│ 系统应用 | 第三方应用(我们开发的就在这一层) │
├─────────────────────────────────────────────────────┤
│ 应用框架层 (Application Framework) │
│ ArkUI | Ability Kit | 分布式软总线 | 各种 Kit │
├─────────────────────────────────────────────────────┤
│ 系统服务层 (System Services) │
│ 分布式调度 | 分布式数据管理 | 图形栈 | 多媒体 │
├─────────────────────────────────────────────────────┤
│ 内核层 (Kernel) │
│ 鸿蒙微内核 | Linux 内核 | LiteOS 内核 │
└─────────────────────────────────────────────────────┘
1.1 分布式软总线:鸿蒙的核心竞争力
分布式软总线是 HarmonyOS 的"灵魂",它实现了近场设备间的高速通信。
工作原理:
设备A ── [Wi-Fi / 蓝牙 / 有线] ── 设备B
↓ ↑
分布式软总线协议栈 ──── 自动发现、认证、组网
核心能力:
- 自动发现:同局域网内的鸿蒙设备自动发现对方
- 高速传输:融合 Wi-Fi 和蓝牙,自适应选择最优通道
- 安全认证:基于华为分布式安全体系的端到端加密
- 统一协议:对上层提供统一的接口,屏蔽底层差异
对应用开发的意义:
- 跨设备数据同步(如收藏在手机和平板间同步)
- 任务流转(如在手机上看一半,流转到平板上继续看)
- 分布式能力调用(如调用智慧屏的音箱播放音乐)
1.2 方舟编译器(ArkCompiler):性能的基石
方舟编译器是鸿蒙应用高性能的关键。它采用 AOT(Ahead-of-Time)编译,将 ArkTS 代码在编译时直接编译成机器码,运行时无需解释执行。
编译流程:
ArkTS 源码
↓
[前端编译器] → 语法分析、类型检查 → ArkTS IR(中间表示)
↓
[优化器] → 内联、常量折叠、死代码消除、逃逸分析
↓
[后端编译器] → 目标机器码(ARM / x86 / RISC-V)
↓
可执行文件(打包进 HAP)
关键优化技术:
| 优化技术 | 作用 | 效果 |
|---|---|---|
| 类型推断 | 利用 ArkTS 类型信息生成更高效的机器码 | 运行速度提升 30-50% |
| 逃逸分析 | 分析对象是否逃逸,决定堆分配还是栈分配 | 减少 GC 压力,内存更省 |
| 方法内联 | 将小函数的代码直接嵌入调用处 | 减少函数调用开销 |
| 常量折叠 | 编译期计算常量表达式 | 运行时零开销 |
| Tree Shaking | 移除未使用的代码和资源 | 包体积更小 |
与 JS 引擎的对比:
// 传统 JS 引擎(如 V8):解释执行 + JIT
// 1. 解析源码 → AST
// 2. 解释执行(慢)
// 3. 热点代码 JIT 编译(有开销)
// 4. 类型变化 → 去优化 → 重新解释
// 方舟编译器:AOT 编译
// 1. 编译期直接生成机器码
// 2. 运行时直接执行,无需解释
// 3. 类型信息在编译期就确定了
// 4. 启动即巅峰,无 JIT 预热过程
这就是为什么鸿蒙原生应用启动快、运行流畅、内存占用低的根本原因。
1.3 ArkUI 声明式开发范式
ArkUI 是鸿蒙的 UI 开发框架,支持两种开发范式:
- ArkTS 声明式开发(推荐,我们用的就是这个)
- JS Web 开发范式(兼容旧版,不推荐新项目用)
声明式 vs 命令式:
// 命令式(典型的 Android/iOS 原生开发)
// ❌ 手动创建、修改、销毁 View
let textView = new TextView();
textView.setText("Hello");
textView.setTextColor(Color.RED);
container.addView(textView);
// 声明式(ArkTS / Flutter / SwiftUI / React)
// ✅ 描述"要什么",框架负责"怎么做"
@Component
struct HelloPage {
@State text: string = "Hello";
build() {
Text(this.text)
.fontColor(Color.Red)
}
}
声明式的核心思想:状态驱动视图
状态变化 → 框架自动 diff → 最小化更新 UI → 渲染到屏幕
这种范式的好处是:
- 代码更简洁,描述性强
- 状态和视图一一对应,不容易出错
- 框架负责 UI 更新的细节,开发者专注业务逻辑
1.4 Ability:应用的基本组件
Ability 是 HarmonyOS 应用的基本组成单元,类似于 Android 的 Activity + Service 的结合体。
Stage 模型下的 Ability 类型:
| 类型 | 基类 | 用途 | 示例 |
|---|---|---|---|
| UIAbility | UIAbility | 有界面的能力 | EntryAbility(主界面) |
| ExtensionAbility | 多种子类 | 无界面的扩展能力 | 备份、分享、搜索 |
Ability 生命周期:
启动
↓
┌───────────┐
│ onCreate │ 初始化
└─────┬─────┘
↓
┌───────────┐
│ onForeground │ 进入前台,可交互
└─────┬─────┘
↓
┌───────────┐
│ onBackground │ 进入后台,不可见
└─────┬─────┘
↓
┌───────────┐
│ onDestroy │ 销毁
└───────────┘
步骤2:「民族图鉴」架构设计深度解析
2.1 整体架构:分层 + 模块化
「民族图鉴」采用经典的分层架构 + 模块化设计:
┌─────────────────────────────────────────────┐
│ 表现层 (Presentation) │
│ pages/ components/ │
│ (页面、组件,纯 UI 逻辑) │
├─────────────────────────────────────────────┤
│ 领域层 (Domain) │
│ models/ │
│ (数据模型、业务实体) │
├─────────────────────────────────────────────┤
│ 服务层 (Service) │
│ services/ utils/ │
│ (业务逻辑、数据处理、工具方法) │
├─────────────────────────────────────────────┤
│ 数据层 (Data) │
│ mock/ (未来可扩展 ApiService/数据库) │
│ (数据来源,mock / 网络 / 本地数据库) │
└─────────────────────────────────────────────┘
依赖规则:上层可以依赖下层,下层不能依赖上层
- pages 可以依赖 services 和 models
- services 可以依赖 models 和 utils
- models 不依赖任何东西(纯数据定义)
- utils 是工具类,被各层使用
2.2 数据流设计:单向数据流 + AppStorage
应用采用单向数据流架构,确保状态可预测、可追踪:
用户交互 → Service 方法 → 更新 AppStorage → @StorageLink 响应 → UI 自动刷新
为什么用 AppStorage 而不是状态管理库?
鸿蒙框架内置了强大的状态管理能力:
| 方案 | 适用场景 | 我们的选择 |
|---|---|---|
| @State | 组件内状态 | ✅ 大量使用 |
| @Prop / @Link | 父子组件间传值 | ✅ 常用 |
| AppStorage + @StorageLink | 全局状态 | ✅ 主题、语言、收藏数等 |
| PersistentStorage | 需要持久化的全局状态 | ✅ 用户设置 |
| 第三方状态库(如 Redux) | 大型复杂应用 | ❌ 暂不需要 |
StorageService 核心实现(节选):
// services/StorageService.ets
/**
* 存储服务 - 单例模式
* 统一管理本地持久化数据,包括浏览历史、收藏、用户设置等
*/
export class StorageService {
private static instance: StorageService;
private preferences: Preferences | null = null;
/**
* 获取单例实例
*/
static getInstance(): StorageService {
if (!StorageService.instance) {
StorageService.instance = new StorageService();
}
return StorageService.instance;
}
/**
* 初始化 Preferences
* 必须在应用启动时调用一次(EntryAbility.onCreate 中)
* @param context 应用上下文
*/
async init(context: Context): Promise<void> {
try {
this.preferences = await dataPreferences.getPreferences(
context,
StorageConstants.PREFS_NAME
);
hilog.info(DOMAIN, TAG, 'StorageService initialized');
} catch (err) {
hilog.error(DOMAIN, TAG, 'init failed: %{public}s', JSON.stringify(err));
throw err;
}
}
/**
* 获取收藏列表
* @returns 收藏的民族 ID 数组
*/
async getFavorites(): Promise<string[]> {
if (!this.preferences) return [];
const jsonStr = await this.preferences.get(
StorageConstants.KEY_FAVORITES,
'[]'
) as string;
try {
return JSON.parse(jsonStr) as string[];
} catch {
return [];
}
}
/**
* 切换收藏状态
* @param ethnicId 民族 ID
* @returns 切换后的收藏状态
*/
async toggleFavorite(ethnicId: string): Promise<boolean> {
const favorites = await this.getFavorites();
const index = favorites.indexOf(ethnicId);
if (index > -1) {
favorites.splice(index, 1);
} else {
favorites.unshift(ethnicId);
}
await this.preferences?.put(
StorageConstants.KEY_FAVORITES,
JSON.stringify(favorites)
);
await this.preferences?.flush();
// 同步到 AppStorage,触发 UI 更新
AppStorage.setOrCreate('favoriteCount', favorites.length);
return index === -1;
}
}
单例模式的设计考量:
- 全局唯一:StorageService 封装 Preferences,全局一个实例即可
- 懒加载:首次调用 getInstance() 时才创建
- 集中管理:所有存储操作都经过 Service,便于统一错误处理和日志
2.3 主题服务:响应式主题切换的实现
主题切换是典型的"状态驱动 UI"场景,也是 AppStorage 的经典应用:
// services/ThemeService.ets
/**
* 主题服务 - 管理主题模式(浅色/深色/跟随系统)和内容模式(全量/基础)
*/
export class ThemeService {
private static instance: ThemeService;
private currentMode: ThemeMode = ThemeMode.SYSTEM;
private currentContentMode: ContentMode = ContentMode.FULL;
static getInstance(): ThemeService {
if (!ThemeService.instance) {
ThemeService.instance = new ThemeService();
}
return ThemeService.instance;
}
/**
* 加载主题设置
* 从本地存储读取用户偏好,同步到 AppStorage
*/
async loadThemeSetting(): Promise<void> {
const storage = StorageService.getInstance();
const savedMode = await storage.getThemeMode();
this.currentMode = savedMode;
// 同步到 AppStorage,所有 @StorageLink 的组件自动响应
AppStorage.setOrCreate('themeMode', this.currentMode);
this.applyTheme();
}
/**
* 应用主题到系统
* 通过设置系统色彩模式触发资源限定符匹配
*/
private applyTheme(): void {
const context = getContext() as Context;
let colorMode: ConfigurationConstant.ColorMode;
switch (this.currentMode) {
case ThemeMode.LIGHT:
colorMode = ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT;
break;
case ThemeMode.DARK:
colorMode = ConfigurationConstant.ColorMode.COLOR_MODE_DARK;
break;
default:
colorMode = ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET;
}
context.getApplicationContext().setColorMode(colorMode);
}
}
主题切换的完整链路:
用户点击切换按钮
↓
调用 ThemeService.setThemeMode(DARK)
↓
更新 AppStorage 中的 themeMode
↓
调用 setColorMode 通知系统
↓
系统资源框架匹配 dark/ 限定符下的资源
↓
所有 $r('app.color.xxx') 自动返回深色模式的值
↓
UI 自动刷新(因为组件绑定的资源变了)
2.4 国际化(I18n)服务:中英双语切换
与主题类似,语言切换也是利用系统资源框架的限定符机制:
// services/I18nService.ets
/**
* 国际化服务 - 管理应用语言设置
*/
export class I18nService {
private static instance: I18nService;
private currentLanguage: AppLanguage = AppLanguage.ZH_CN;
static getInstance(): I18nService {
if (!I18nService.instance) {
I18nService.instance = new I18nService();
}
return I18nService.instance;
}
/**
* 切换语言
* @param language 目标语言
*/
async setLanguage(language: AppLanguage): Promise<void> {
this.currentLanguage = language;
const context = getContext() as Context;
const locale = language === AppLanguage.ZH_CN ? 'zh-CN' : 'en';
// 通知系统切换语言,触发资源限定符重新匹配
context.getApplicationContext().setLocale(locale);
AppStorage.setOrCreate('appLanguage', language);
await StorageService.getInstance().setLanguage(language);
}
}
资源限定符的匹配优先级:
当系统需要找一个资源时(如 app.string.app_name),按以下顺序查找:
1. zh_CN/element/string.json(最具体,中文简体)
2. zh/element/string.json(中文通用)
3. base/element/string.json(默认,兜底)
如果当前语言是英文:
1. en/element/string.json
2. base/element/string.json
这就是为什么我们在 resources/ 下有 zh_CN/、en/、dark/ 等目录——系统会根据当前状态自动选择最合适的资源。
步骤3:100篇文章知识体系全景
七大篇章的能力进阶路径
第1-10篇 入门基础 ──── 零基础 → 能跑起来
│
↓
第11-30篇 页面开发 ──── 能跑起来 → 能做出完整页面
│
↓
第31-45篇 数据服务 ──── 能做出页面 → 懂架构设计
│
↓
第46-60篇 功能进阶 ──── 懂架构 → 能实现复杂功能
│
↓
第61-70篇 性能优化 ──── 能实现功能 → 能做好性能
│
↓
第71-90篇 鸿蒙7新特性 ── 能做好性能 → 懂前沿技术
│
↓
第91-100篇 实战项目 ──── 懂前沿技术 → 能独立完成项目
鸿蒙7(API 26)20篇专题规划
这 20 篇是本系列的差异化亮点,每篇都深度结合「民族图鉴」项目:
| 序号 | 主题 | 核心知识点 | 对应模块 |
|---|---|---|---|
| 71 | 鸿蒙7全景 | 五大创新方向、九大Kit升级、架构演进 | 全景 |
| 72 | Skill技能开发 | 小艺技能接入、语音指令、意图匹配 | AI助手 |
| 73 | Agent智能体 | A2A协议、Agent开发框架、系统级入口 | AI助手 |
| 74 | 视觉AI能力 | 视觉大模型、端侧推理、场景化控件 | 图片工具 |
| 75 | 图像超分AI | SR算法、性能优化、老照片修复 | 图片工具 |
| 76 | 本地文搜图 | CLIP模型、向量检索、隐私计算 | 图片工具 |
| 77 | 沉浸光感组件 | 光随指动、光线勾勒、空间感提升 | 详情页 |
| 78 | 3DGS端侧重建 | 高斯溅射、单图生成3D、实时渲染 | 3D文物馆 |
| 79 | 空间音频 | 3D声场、音频节点、沉浸式体验 | 音乐馆 |
| 80 | 闪控悬浮窗 | 悬浮球、侧边栏、后台播放控制 | 音乐馆 |
| 81 | 互动卡片升级 | 动效卡片、摇一摇、前景出框 | 首页卡片 |
| 82 | 多形态窗口 | 折叠屏、分屏、多实例 | 全页面 |
| 83 | 碰一碰分享 | 近场通信、精准分享、跨设备协同 | 分享功能 |
| 84 | 分布式同步 | 分布式数据、端云协同、断点续传 | 数据服务 |
| 85 | 原子化服务 | 免安装、服务卡片、桌面快捷方式 | 新形态 |
| 86 | 端云一体化 | 云数据库、云存储、Serverless | 架构升级 |
| 87 | LTPO动态帧率 | 可变刷新率、功耗优化、平滑过渡 | 性能优化 |
| 88 | 应用快启 | 预启动、内存优化、Graphics加速 | 性能优化 |
| 89 | QUIC长连接 | QUIC协议、弱网优化、传输加速 | 网络优化 |
| 90 | ArkWeb内核升级 | Chromium 144、Web增强、离线缓存 | 百科扩展 |
⚠️ 常见问题与解决方案
问题1:鸿蒙原生开发会不会"锁死"在华为生态?
现象:
担心学了鸿蒙原生,只能做华为设备,就业面窄。
分析:
技术层面:
- ArkTS 是 TypeScript 的超集,学会了 TS 基础是通用的
- 声明式 UI 思想是通用的(Flutter/SwiftUI/Compose/React 都是声明式)
- 架构设计、性能优化、工程化等能力是跨平台通用的
生态层面:
- 鸿蒙生态高速增长,2025 年已突破 20% 市场份额
- 纯血鸿蒙(NEXT)不兼容安卓,原生开发需求会越来越大
- 华为"1+8+N"全场景战略,设备形态丰富
职业发展层面:
// ❌ 担心:只会鸿蒙,万一凉了怎么办?
// ✅ 实际上:
// 1. 鸿蒙的核心是 TypeScript + 声明式 UI,这俩是通用技能
// 2. 你学的不是"鸿蒙",是"移动端应用开发",鸿蒙只是载体
// 3. 早期入局者往往有先发优势,生态成长期机会最多
建议:
- 不要把自己定义为"鸿蒙开发者",要定义为"客户端开发者"
- 鸿蒙是主技能,同时保持对其他平台的了解
- 重点培养架构设计、性能优化、工程化等可迁移能力
问题2:"一次开发,多端部署"是真的吗?还是噱头?
现象:
宣传说鸿蒙应用"一次开发,多端部署",实际开发中真的能做到吗?
真实情况:
能做到的:
- ✅ 代码复用:业务逻辑、数据模型、工具类 100% 复用
- ✅ UI 复用:通用组件大部分可以复用
- ✅ 资源复用:颜色、字符串、图片等资源统一管理
需要适配的:
- ⚠️ 布局差异:手机、平板、手表的屏幕尺寸差很大,需要响应式布局
- ⚠️ 交互差异:触控、遥控器、旋转表冠的交互方式不同
- ⚠️ 能力差异:不同设备支持的系统能力不一样
- ⚠️ 性能差异:低端 IoT 设备性能有限,需要做性能降级
实际开发中的策略:
// 理想:一套代码跑所有设备
// 现实:核心逻辑一套,UI 分层适配
// 目录组织
common/ // 通用代码(所有设备复用)
phone/ // 手机专属 UI
tablet/ // 平板专属布局
wearable/ // 手表专属页面
// 复用比例:70-80% 代码复用,20-30% 需要设备适配
结论:不是"写一次,完全不用改",而是"写一次,适配成本比从零开发低很多"。跨端复用是真实存在的,但不是银弹。
问题3:Stage模型 vs FA模型,有什么区别?
现象:
经常听到 Stage 模型、FA 模型,不知道什么意思,该用哪个。
对比分析:
| 维度 | FA 模型(旧) | Stage 模型(新) |
|---|---|---|
| 引入版本 | HarmonyOS 1.0 | HarmonyOS 3.1 / API 9 |
| 组件模型 | 每个 Ability 一个页面 | Ability + 页面路由分离 |
| 包结构 | HAP = Ability + 资源 | HAP = 多个 Ability + 资源 |
| 页面管理 | Ability 管理页面 | pages 配置路由 |
| 代码组织 | 比较分散 | 更清晰,模块化好 |
| 启动性能 | 一般 | 更优(Stage 预加载) |
| 推荐程度 | 维护中,不推荐新项目 | ✅ 推荐所有新项目 |
为什么 Stage 模型更好?
// FA 模型问题:
// - 一个 Ability 管一个页面,页面多了 Ability 爆炸
// - 页面跳转 = Ability 跳转,开销大
// - 代码组织混乱
// Stage 模型优势:
// - 一个 EntryAbility 管所有页面
// - 页面跳转用 router,轻量高效
// - 结构清晰,符合现代前端开发习惯
// - 支持多模块、动态特性
结论:
- 新项目必须用 Stage 模型
- FA 模型是历史遗产,只在维护老项目时才会遇到
- 本系列全部基于 Stage 模型
问题4:为什么用 ArkTS 而不是 JavaScript?
现象:
JS 开发者更多,生态更丰富,为什么鸿蒙主推 ArkTS?
ArkTS vs JS:
| 维度 | JavaScript | ArkTS |
|---|---|---|
| 类型系统 | 动态类型,运行时检查 | 静态类型,编译期检查 |
| 编译方式 | 解释执行 + JIT | AOT 编译为机器码 |
| 性能 | 中等 | 更高(30-50%) |
| 开发体验 | 灵活但容易出 bug | 类型安全,IDE 提示好 |
| 重构成本 | 高(改了不知道哪炸) | 低(编译器帮你检查) |
| 大型项目 | 维护困难 | 更可维护 |
为什么鸿蒙选择 TypeScript 路线?
- 性能:静态类型 = 编译期可优化空间大 = 运行更快
- 可维护性:大型项目类型系统是刚需
- IDE 体验:类型推导 = 更好的代码补全、重构支持
- 生态:TypeScript 已是前端主流,学习资源丰富
// ❌ JS 的痛点:运行时才发现类型错误
function add(a, b) {
return a + b; // 传两个数字?两个字符串?没人知道
}
// ✅ ArkTS 的优势:编译期就发现问题
function add(a: number, b: number): number {
return a + b; // 类型明确,传错了编译直接报错
}
结论:
- 如果你是前端开发者,拥抱 TypeScript/ArkTS 是趋势
- 类型系统不是"束缚",是"保护"
- 越大型的项目,类型系统的价值越大
问题5:本系列项目的代码能直接用于生产环境吗?
现象:
想把项目模板拿去改改就上线,不知道够不够"生产级"。
诚实回答:
已经做到生产级的部分:
- ✅ 架构设计:分层清晰,模块化合理
- ✅ 状态管理:AppStorage + Service,稳定可靠
- ✅ 主题/国际化:利用系统能力,标准做法
- ✅ 存储服务:Preferences 封装,错误处理完善
- ✅ 资源管理:限定符 + rawfile,规范使用
可以继续加强的部分:
- ⚠️ 数据来源:目前是 Mock 数据,生产环境需要接入后端 API
- ⚠️ 错误边界:可以增加全局异常捕获和降级策略
- ⚠️ 埋点统计:用户行为数据采集(合规前提下)
- ⚠️ 测试覆盖:单元测试、UI 测试、性能测试
- ⚠️ 安全加固:混淆、加壳、安全检测
- ⚠️ 离线缓存:网络异常时的降级策略
建议:
- 本项目作为学习模板和基础框架是完全合格的
- 拿去做生产项目,需要根据业务需求补充后端对接、安全加固、测试等
- 后续的实战篇会覆盖部分内容,但生产环境永远是具体问题具体分析
📝 本章小结
核心知识点
本文作为系列开篇,从技术架构、项目设计、学习路线三个维度进行了深度讲解:
1. HarmonyOS 技术架构
- 四层架构:应用层 → 应用框架层 → 系统服务层 → 内核层
- 分布式软总线:鸿蒙的灵魂,近场设备高速通信
- 方舟编译器:AOT 编译,类型优化,逃逸分析,性能卓越
- ArkUI 声明式开发:状态驱动视图,简洁高效
- Ability 模型:应用的基本组成单元,Stage 模型是推荐方式
2. 「民族图鉴」架构设计
- 四层架构:表现层 → 领域层 → 服务层 → 数据层
- 单向数据流:用户操作 → Service → AppStorage → UI 响应
- 单例服务模式:StorageService / ThemeService / I18nService
- 资源限定符系统:dark / zh_CN / en 等自动匹配
3. 100 篇学习路线
- 七大篇章,循序渐进
- 20 篇鸿蒙 7 新特性,差异化亮点
- 从零基础到独立完成项目的完整路径
最佳实践总结
✅ 架构先想清楚再动手
不要上来就写代码,先想清楚:
- 分几层?每层职责是什么?
- 状态怎么管理?数据流向哪里?
- 哪些模块可能变?提前留好扩展点?
好的架构让开发事半功倍,烂的架构让你天天还债。
✅ 善用系统能力,不要重复造轮子
// 主题切换不用自己写条件渲染
// 语言切换不用自己维护字符串 Map
// 鸿蒙的资源限定符系统已经做好了
// 用 $r() + dark/zh_CN/en 目录就搞定了
// ✅ 正确做法:用系统资源限定符
.backgroundColor($r('app.color.background'))
// 系统自动根据当前模式选 dark/ 或 base/ 下的颜色
✅ 单例模式管理全局服务
// 存储、主题、语言这些全局服务,用单例模式
// 好处:
// 1. 全局唯一,状态一致
// 2. 初始化一次,性能好
// 3. 集中管理,便于维护
// 经典写法
export class XxxService {
private static instance: XxxService;
static getInstance(): XxxService {
if (!XxxService.instance) {
XxxService.instance = new XxxService();
}
return XxxService.instance;
}
}
下一步预告
在下一篇文章中,我们将:
- 🛠️ 安装配置 DevEco Studio,详解每个配置项的含义
- 📦 深入理解 HarmonyOS SDK 的目录结构和各组件作用
- 🔑 掌握签名证书的原理与配置方法
- 🚀 启动第一个应用,理解构建与安装流程
- 🔍 学习环境问题的系统排查方法论
🔗 相关链接
- 项目源码: GitCode 仓库
- HarmonyOS 官方文档: developer.harmonyos.com
- ArkTS 语言规范: ArkTS 官方指南
- 方舟编译器: ArkCompiler 介绍
- 分布式软总线: 技术白皮书
💡 提示:第一篇内容偏多,主要是建立整体认知。如果有些概念看不懂很正常,随着后续的实践,你会逐渐理解。建议先通读一遍有个印象,学到具体章节时再回头看,会有更深的理解。
更多推荐




所有评论(0)