name: harmonyos-dev
description: >
HarmonyOS 應用開發技能(覆蓋 5.0~6.1 版本)。基於 ArkTS 語言,支援 Stage 模型應用開發、
ArkUI 宣告式 UI、UIAbility 生命週期、資源管理、許可權配置、媒體處理、AI 整合、
分散式流轉等完整開發流程。當用戶提到 HarmonyOS、鴻蒙應用開發、ArkTS、Stage模型、
HAP/HAR/HSP 包開發、ArkUI 元件、分散式能力時觸發。
trigger: HarmonyOS|鴻蒙|鴻蒙應用|ArkTS|Stage模型|HAP|HAR|HSP|ArkUI|UIAbility|DevEco|鴻蒙開發|harmonyos|HarmonyOS應用|分散式能力|AbilityKit|ohos.net|@kit
tags:
- harmonyos
- arkts
- arkui
- stage-model
- harmonyos-dev
- huawei
hermes:
tags: [harmonyos, arkts, arkui, stage-model, harmonyos-dev, huawei, ability, hap, har, hsp]
related_skills: [apple-design, frontend-design]
version: "2.0.0"
last_updated: "2026-04-23"
source: |
https://developer.huawei.com/consumer/cn/doc/harmonyos-guides
https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/introduction-to-arkts
https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-basic-syntax-overview
https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/application-configuration-file-stage
https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/resource-categories-and-access
license: MIT
HarmonyOS 開發技能
概述
HarmonyOS 是華為的分散式作業系統,應用預設使用 ArkTS 語言開發,基於 Stage 模型。
來源
小蔥技能7w4.net持續更新中。
來源:華為 HarmonyOS 開發者文件(2026-04-23 訪問)
- 文件中心:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides
- ArkTS 語言:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/introduction-to-arkts
- ArkUI 框架:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-basic-syntax-overview
- Stage 模型:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/application-configuration-file-stage
- 資源管理:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/resource-categories-and-access
更新頻率:隨 HarmonyOS 版本迭代(當前覆蓋 5.0~6.1)
快速開發路徑
- 環境:DevEco Studio(方舟開發編輯器)
- 語言:ArkTS(TypeScript 超集,靜態型別+宣告式 UI)
- 框架:ArkUI(宣告式 UI 框架)
- 模型:Stage 模型(推薦)
文件導航
入門
ArkTS 語言
應用框架
ArkUI
ArkTS 語言基礎
核心概念速查
ArkTS vs TypeScript 關鍵差異(API version 10+)
ArkTS 在 TS 基礎上做了以下限制:
1. 強制靜態型別 — 所有變數必須有確定型別,禁止執行期改變物件佈局
2. 禁止 Structural Typing — 不支援按結構匹配型別
3. 限制運算子語義 — 一元加法僅能作用於數字
4. 所有型別預設非空 — let x: number = null 編譯錯誤,需宣告為 number | null
Module 型別(HAP/HAR/HSP)
| 型別 |
說明 |
使用場景 |
| HAP |
HarmonyOS Ability Package |
應用主包,可安裝 |
| HAR |
HarmonyOS Archive |
靜態共享庫,編譯時打包 |
| HSP |
HarmonyOS Shared Package |
動態共享庫,執行時共享 |
資源目錄結構
resources/
├── base/
│ ├── element/ # 字串、顏色、尺寸等元素資源
│ ├── media/ # 圖片、音影片等媒體資源
│ └── profile/ # 自定義配置檔案
├── zh_CN/ # 限定詞目錄(語言_地區-橫豎屏-裝置型別-顏色模式-螢幕密度)
├── dark/ # 深色模式
└── rawfile/ # 原始檔案,不編譯
資源訪問:$r('app.type.name') 或 $rawfile('path/file.png')
系統資源:$r('sys.type.name')
典型開發流程
典型開發流程
- 建立工程:DevEco Studio 新建專案,選 Stage 模型 + ArkTS
- 編寫 UI:
.ets 檔案,用 @Component + build() 宣告 UI
- 配置 Ability:在
module.json5 中註冊 UIAbility/EntryAbility
- 管理資源:在
resources/ 下按限定片語織資原始檔
- 構建除錯:DevEco Studio 內建 hvigor 構建系統
- 釋出應用:簽名打包 HAP,通過 AppGallery Connect 釋出
完整頁面示例(ArkUI + MVVM)
// Model
interface User {
id: number;
name: string;
email: string;
}
// ViewModel(使用 TaskPool 進行網路請求)
import { taskpool } from '@kit.ArkTS';
@Concurrent
async function fetchUsersFromServer(): Promise<User[]> {
// 模擬網路請求
const response = await http.createHttp();
const result = await response.request('https://api.example.com/users');
return JSON.parse(result.result as string) as User[];
}
// ViewModel
class UserListViewModel {
@State users: User[] = [];
@State isLoading: boolean = false;
@State error: string = '';
async loadUsers() {
this.isLoading = true;
this.error = '';
try {
const task = new taskpool.Task(fetchUsersFromServer);
this.users = await taskpool.execute(task) as User[];
} catch (e) {
this.error = (e as Error).message;
} finally {
this.isLoading = false;
}
}
}
// View
@Entry
@Component
struct UserListPage {
@State viewModel: UserListViewModel = new UserListViewModel();
build() {
Column() {
// 標題欄
Row() {
Text('使用者列表')
.fontSize(24)
.fontWeight(FontWeight.Bold)
Blank()
if (this.viewModel.isLoading) {
ProgressView()
.width(24)
.height(24)
}
}
.width('100%')
.padding(16)
.backgroundColor(Color.White)
// 錯誤提示
if (this.viewModel.error) {
Text(`錯誤: ${this.viewModel.error}`)
.fontColor(Color.Red)
.fontSize(14)
.padding(16)
}
// 使用者列表
List({ space: 10 }) {
ForEach(this.viewModel.users, (user: User) => {
ListItem() {
this.UserItem(user)
}
.swipeAction({ end: this.DeleteAction(user.id) })
}, (user: User) => user.id.toString())
}
.width('100%')
.layoutWeight(1)
.padding(16)
}
.width('100%')
.height('100%')
.backgroundColor('#F5F5F5')
.onAppear(() => {
this.viewModel.loadUsers();
})
}
@Builder
UserItem(user: User) {
Row({ space: 12 }) {
Column() {
Text(user.name)
.fontSize(17)
.fontWeight(FontWeight.Medium)
Text(user.email)
.fontSize(14)
.fontColor('#666666')
}
.alignItems(HorizontalAlign.Start)
Blank()
Text(`#${user.id}`)
.fontSize(12)
.fontColor('#999999')
}
.width('100%')
.padding(16)
.backgroundColor(Color.White)
.borderRadius(12)
}
@Builder
DeleteAction(id: number) {
Button('刪除')
.type(ButtonType.Normal)
.height('100%')
..width(80)
.backgroundColor(Color.Red)
.onClick(() => {
// 刪除邏輯
const index = this.viewModel.users.findIndex(u => u.id === id);
if (index >= 0) {
this.viewModel.users.splice(index, 1);
}
})
}
}
EntryAbility 配置(module.json5)
{
"module": {
"name": "entry",
"type": "entry",
"description": "$string:module_desc",
"mainElement": "EntryAbility",
"deviceTypes": ["phone", "tablet"],
"deliveryWithInstall": true,
"installationFree": false,
"pages": "$profile:main_pages",
"abilities": [
{
"name": "EntryAbility",
"srcEntry": "./ets/entryability/EntryAbility.ets",
"description": "$string:EntryAbility_desc",
"icon": "$media:icon",
"label": "$string:EntryAbility_label",
"startWindowIcon": "$media:icon",
"startWindowBackground": "$color:start_window_background",
"exported": true,
"skills": [
{
"entities": ["entity.system.home"],
"actions": ["action.system.home"]
}
]
}
]
}
}
資原始檔(resources/base/element/string.json)
{
"string": [
{
"name": "module_desc",
"value": "使用者列表演示應用"
},
{
"name": "EntryAbility_desc",
"value": "主入口Ability"
},
{
"name": "EntryAbility_label",
"value": "使用者列表"
}
]
}
架構與網路
架構模式
ArkUI MVVM 架構
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ View │ ←── │ ViewModel │ ←── │ Model │
│ (@Component)│ │ (@State/@Link)│ │ (interface) │
└─────────────┘ └──────────────┘ └─────────────┘
build() @State 資料結構
@Builder @Link 函式
資料流向:
1. View 通過 @State/@Link 繫結 ViewModel 的狀態
2. ViewModel 處理業務邏輯,呼叫 Service/Repository
3. Model 定義資料結構(interface)
4. 狀態變化自動觸發 UI 重新渲染
狀態管理對比
| 裝飾器 |
作用域 |
繼承 |
父傳子 |
適用場景 |
| @State |
元件內 |
❌ |
❌ |
簡單狀態 |
| @Link |
元件內 |
❌ |
✅ |
雙向繫結 |
| @Prop |
元件內 |
❌ |
✅單向 |
純展示 |
| @ObjectLink |
元件內 |
✅ |
✅ |
複雜物件 |
| @StorageLink |
持久化 |
❌ |
❌ |
全域性持久 |
| AppStorage |
應用級 |
❌ |
❌ |
全域性狀態 |
網路層封裝
// 統一網路服務
class HttpService {
private baseUrl = 'https://api.example.com';
async request<T>(config: RequestConfig): Promise<T> {
const http = http.createHttp();
try {
const response = await http.request(this.baseUrl + config.url, {
method: config.method || 'GET',
header: config.headers,
extraData: config.body,
connectTimeout: 30000,
readTimeout: 30000
});
http.destroy();
return JSON.parse(response.result as string) as T;
} catch (e) {
http.destroy();
throw e;
}
}
get<T>(url: string): Promise<T> {
return this.request<T>({ url, method: 'GET' });
}
post<T>(url: string, body: object): Promise<T> {
return this.request<T>({ url, method: 'POST', body });
}
}
// 使用
const httpService = new HttpService();
const users = await httpService.get<User[]>('/users');
持久化方案
| 方案 |
適用場景 |
容量 |
效能 |
| AppStorage |
鍵值對 |
小 |
高 |
| relationalStore |
結構化資料 |
中 |
中 |
| userinfoStore |
使用者資料 |
中 |
中 |
| requestDataHelper |
簡單儲存 |
小 |
高 |
// AppStorage 使用
AppStorage.setOrCreate('username', 'John');
const username = AppStorage.get<string>('username');
// 持久化儲存
import { userinfoStore } from '@kit.ArkData';
let context = getContext(this);
const store = await userinfoStore.getUserinfoStorageInstance(context);
await store.insert('user', { name: 'John', age: 30 });
const result = await store.query('user', []);
路由管理
import router from '@ohos.router';
// 路由配置(main_pages.json)
{
"src": [
{
"name": "Home",
"pageSourceFile": "./ets/pages/Home/Home.ets",
"window": { "designWidth": 720 }
},
{
"name": "Detail",
"pageSourceFile": "./ets/pages/Detail/Detail.ets"
}
]
}
// 路由跳轉
router.pushUrl({ url: 'pages/Detail/Detail', params: { id: 123 } });
// 獲取引數
const params = router.getParams() as { id: number };
依賴注入(Kit 方式)
// 方式一:直接匯入
import { UIAbility, AbilityConstant, Want } from '@kit.AbilityKit';
// 方式二:服務發現
import serviceDiscovery from '@kit.ArkUI';
// 方式三:@ohos 相容方式(已廢棄,不推薦)
import UIAbility from '@ohos.app.ability.UIAbility';
效能最佳化
| 場景 |
方案 |
說明 |
| 長列表 |
LazyForEach |
懶載入,僅渲染可見項 |
| 圖片 |
Image + async load |
支援網路圖片 |
| 資料持久化 |
relationalStore |
SQLite 資料庫 |
| 並行任務 |
taskpool |
多執行緒並行 |
| 預載入 |
prefetch |
提前載入資料 |
| 減少重新整理 |
@ObjectLink |
細粒度更新 |
任務池(TaskPool)
import { taskpool } from '@kit.ArkTS';
// 定義併發函式
@Concurrent
function heavyTask(numbers: number[]): number {
return numbers.reduce((sum, n) => sum + n, 0);
}
// 執行任務
let task = new taskpool.Task(heavyTask, [[1, 2, 3, 4, 5]]);
let result = await taskpool.execute(task);
// 取消任務
taskpool.cancelTask(task);
測試策略
// 單元測試(import test from '@kit.ArkTS')
import test from '@kit.ArkTS';
@Entry
@Component
struct Calc {
@State result: number = 0;
add(a: number, b: number): number {
return a + b;
}
}
// UI 測試:使用 DevEco Studio 內建測試框架
// 效能測試:使用 hdc hilog 抓取效能日誌
除錯技巧
| 工具 |
用途 |
| DevEco Studio |
斷點除錯、日誌檢視 |
| hitrace |
分散式追蹤 |
| hdc shell |
命令列除錯 |
| AppGallery Connect |
遠端除錯、效能監控 |
// 日誌列印
import hilog from '@ohos.hilog';
hilog.info(0x0000, 'UserModule', 'User login: %{public}s', username);
// 條件斷點
// 在 DevEco Studio 中設定條件表示式
快速參考
ArkUI 常用元件速查
| 元件 |
用途 |
關鍵屬性 |
| Text |
文本顯示 |
.fontSize(), .fontColor(), .fontWeight() |
| Image |
圖片 |
.src(), .width(), .height(), .borderRadius() |
| Button |
按鈕 |
.type(), .onClick(), .backgroundColor() |
| TextInput |
輸入框 |
.placeholder(), .text(), .onChange() |
| List |
列表 |
ForEach, ListItem, .onScrollIndex() |
| Grid |
網格 |
ForEach, ListItem, .columnsTemplate() |
| Column |
垂直佈局 |
.spacing(), .alignItems() |
| Row |
水平佈局 |
.spacing(), .justifyContent() |
| Stack |
層疊佈局 |
.alignContent() |
| Flex |
彈性佈局 |
.direction(), .wrap() |
| Navigator |
路由導航 |
.target(), .type() |
| Dialog |
對話方塊 |
.title(), .content() |
| ActionSheet |
操作選單 |
.actions() |
| LoadingProgress |
載入指示器 |
.width(), .height() |
| Badge |
徽章 |
.count(), .maxCount() |
| Tabs |
標籤頁 |
.barPosition(), .controller() |
ArkTS 型別速查
| 型別 |
語法 |
示例 |
| 基礎型別 |
string, number, boolean |
let name: string = 'John' |
| 陣列 |
Type[] |
let nums: number[] = [1, 2, 3] |
| 元組 |
[Type, Type] |
let t: [string, number] = ['age', 30] |
| 列舉 |
enum Name { A, B } |
enum Color { Red, Blue } |
| 介面 |
interface Name { } |
interface User { id: number; name: string; } |
| 可空 |
Type \| null |
let x: number \| null = null |
| 聯合 |
A \| B \| C |
let v: string \| number \| boolean |
| 字面量 |
'a' \| 'b' \| 'c' |
type Direction = 'up' \| 'down' |
| 函式 |
(params) => returnType |
let fn: (n: number) => number |
| 類 |
class Name { } |
class User { name: string; } |
| 泛型 |
Type<T> |
let arr: Array<number> |
HarmonyOS 許可權速查
| 許可權 |
用途 |
級別 |
| ohos.permission.INTERNET |
網路訪問 |
normal |
| ohos.permission.GET_NETWORK_INFO |
獲取網路資訊 |
restricted |
| ohos.permission.CAMERA |
相機 |
restricted |
| ohos.permission.MICROPHONE |
麥克風 |
restricted |
| ohos.permission.RECORD_AUDIO |
錄音 |
restricted |
| ohos.permission.READ_CONTACTS |
讀聯絡人 |
restricted |
| ohos.permission.WRITE_CONTACTS |
寫聯絡人 |
restricted |
| ohos.permission.LOCATION |
位置 |
restricted |
| ohos.permission.STORAGE |
儲存 |
restricted |
常用 API 速查
| 功能 |
模組 |
方法 |
| HTTP請求 |
@kit.NetworkKit |
http.createHttp() |
| 檔案操作 |
@kit.CoreFileKit |
fileio |
| 偏好設定 |
@kit.AbilityKit |
AppStorage |
| 彈窗 |
@kit.ArkUI |
promptAction |
| 路由 |
@kit.ArkUI |
router |
| 圖片 |
@kit.MediaKit |
image |
| 影片 |
@kit.MediaKit |
video |
| 音訊 |
@kit.MediaKit |
audio |
| 動畫 |
@kit.ArkUI |
animateTo |
| 手勢 |
@kit.ArkUI |
gesture |
| 執行緒池 |
@kit.ArkTS |
taskpool |
佈局速查
// 垂直佈局 Column
Column({ space: 10 }) {
Text('Header')
Row() { /* 內容 */ }
}
.width('100%')
.height('100%')
.alignItems(HorizontalAlign.Center)
.justifyContent(FlexAlign.Center)
// 水平佈局 Row
Row({ space: 12 }) {
Image('icon.png').width(24).height(24)
Text('Label')
Blank()
Text('Value')
}
.width('100%')
.padding(16)
// 彈性佈局 Flex
Flex({ direction: FlexDirection.Row, wrap: FlexWrap.Wrap }) {
ForEach(items, (item) => {
ItemComponent({ item: item })
.width('30%')
.margin(5)
})
}
// 層疊佈局 Stack
Stack() {
Background()
Content()
FloatingButton()
}
.alignContent(Alignment.BottomEnd)
生命週期速查
| 階段 |
說明 |
回撥 |
| 建立 |
元件建立 |
aboutToAppear() |
| 渲染 |
UI 構建 |
build() |
| 銷燬 |
元件銷燬 |
aboutToDisappear() |
| 頁面顯示 |
頁面展示 |
onPageShow() |
| 頁面隱藏 |
頁面隱藏 |
onPageHide() |
| 許可權變更 |
許可權回撥 |
onAbilityConnectDone() |
版本相容性速查
| 版本 |
支援特性 |
| API 9 |
基礎 ArkTS + Stage 模型 |
| API 10 |
增強型別系統 |
| API 11 |
效能最佳化 |
| API 12 |
@kit 匯入方式 |
| API 22 |
HTTP 攔截器 |
常見 ArkTS 模式
常見 ArkTS 模式
狀態管理
@Entry
@Component
struct MyPage {
@State message: string = 'Hello';
build() {
Column() {
Text(this.message)
}
}
}
匯入 HarmonyOS SDK
// 方式一:Kit 方式(推薦)
import { UIAbility, Ability, Context } from '@kit.AbilityKit';
// 方式二:直接模組
import UIAbility from '@ohos.app.ability.UIAbility';
動態匯入
async function loadModule() {
let module = await import('./Calc');
module.add(3, 5);
}
參考文件
| 檔案 |
內容 |
references/arkts-language.md |
ArkTS 完整語法(型別/函式/類/介面/泛型/運算子/語句/模組/註解) |
references/arkui-quickref.md |
ArkUI 元件、裝飾器、佈局、路由、生命週期、動畫、手勢 |
references/stage-config.md |
Stage 模型配置 + 視窗管理(UIAbility/子視窗/沉浸式/懸浮窗) |
references/app-package.md |
HAP/HAR/HSP 包結構、Stage 模型配置 |
references/resource-management.md |
資源目錄、$r/$rawfile/$sys 語法、限定詞、overlay、AppStorage |
references/network-http.md |
HTTP 請求、WebSocket、檔案上傳下載、攔截器、證書配置 |
references/permission-testing.md |
許可權宣告與動態請求、應用測試(單元/UI/效能)、簽名釋出流程、hvigor 構建 |
references/media-ai-distributed.md |
媒體處理(image/video/audio)、Canvas、AI 能力、分散式資料、流轉 |
|
references/glossary.md |
避坑指南
ArkTS 編譯期強制規則
| 錯誤做法 |
正確做法 |
❌ let x = null |
✅ let x: number \| null = null(所有型別預設非空) |
❌ obj instanceof Class 用於介面 |
✅ instanceof 僅限 Class,不支援介面型別 |
| ❌ 物件字面量隨意擴屬性 |
✅ 禁止執行期改變物件佈局 |
| ❌ 動態增加物件屬性 |
✅ 靜態型別禁止 |
| ❌ 一元加法用於非數字 |
✅ +str 會報錯,一元加法僅能作用於數字 |
ArkUI 執行時注意
| 錯誤做法 |
正確做法 |
❌ 在 aboutToDisappear() 修改狀態 |
✅ 該方法禁止修改 @State,會觸發 UI 異常 |
❌ LazyForEach 不提供唯一鍵函式 |
✅ 必須提供 (item) => item.id 型別的唯一鍵 |
❌ HTTP 請求忘記 destroy() |
✅ 每次請求後呼叫 httpRequest.destroy() 防記憶體洩漏 |
❌ router.pushUrl() 傳複雜物件 |
✅ params 僅支援基本型別,複雜資料用 AppStorage |
❌ 元件內直接修改 @Prop |
✅ @Prop 是單向傳遞,只能父元件修改 |
Stage 模型注意
| 錯誤做法 |
正確做法 |
❌ module.json5 的 srcEntry 路徑錯誤 |
✅ 路徑相對於專案根目錄,如 ./ets/entryability/EntryAbility.ts |
❌ 混淆 HAP/HAR/HSP 用途 |
✅ HAP 可安裝,HAR 編譯時打包,HSP 執行時共享 |
| ❌ 免安裝應用配置錯誤 |
✅ installationFree: true 時 deliveryWithInstall 必須為 false |
| ❌ 許可權只宣告不動態請求 |
✅ 敏感許可權需同時宣告和動態請求 |
| ❌ 多裝置場景硬編碼 deviceId |
✅ 空字串 '' 表示本裝置,顯式 deviceId 用於跨裝置 |
版本陷阱
- ⚠️ API v22+ — HTTP 攔截器需要 API version 22+
- ⚠️ Kit 方式匯入 —
@kit.AbilityKit 是 API v22+ 推薦方式
- ⚠️ 註解限制 — 註解僅在
.ets/.d.ets 檔案有效,release 混淆會被移除
- ⚠️ 註解欄位型別 — 僅支援
boolean/number/string 及其陣列
- ⚠️ Flex 佈局 — 預設不換行,需要
wrap: FlexWrap.Wrap 才能換行
- ⚠️ Grid 迴圈 —
ForEach 在 Grid 內必須配合 ListItem() 使用
輸出格式規範
當使用本技能回答使用者問題時,遵循以下格式:
回覆結構
- 直接回答 — 一段簡潔的話給出核心答案
- 程式碼示例 — ArkTS/ArkUI 示例程式碼(按需)
- 避坑提醒 — 常見錯誤+正確做法
- 文件連結 — 華為開發者文件相關連結(如適用)
示例回覆(ArkTS 空安全)
ArkTS 所有型別預設非空,let x: number = null 會編譯錯誤。正確做法是宣告為 let x: number | null = null。訪問可空變數時用 ?? 合併運算子:this.nick ?? ''。如果確認變數有值,可用 ! 非空斷言,但需確保執行時不為空。
停用格式
- ❌ 不要顯式分層(避免"第一層/第二層/框架分析"等字眼)
- ❌ 不要長篇引用華為文件,要內化為自己的話
- ✅ 輸出應是一段乾淨的話