鸿蒙 6 新华字典实战:从零到一用 ArkTS 开发原生鸿蒙应用
**注意**:`data` 是数组而非单个对象,且字段名为 `radical`(单数)而非 `radicals`。**解决**:`extraData` 需要 `JSON.stringify()` 序列化,同时 `Content-Type` 必须设为 `application/json`。**解决**:确认 SDK 版本对应的 API。或者在设备设置中关闭开发者模式。**解决**:自定义 UI 方法
·
# 鸿蒙 6 新华字典实战:从零到一用 ArkTS 开发原生鸿蒙应用
## 一、背景
HarmonyOS 6.0 发布以来,鸿蒙原生应用生态快速发展。作为一名开发者,我决定用 ArkTS 和 ArkUI 开发一款实用的新华字典应用,通过对接 ALAPI 新华字典接口,实现汉字查询、拼音、部首、笔画、释义等完整功能。
本文将从项目初始化、UI 搭建、网络请求、设备调试到最终部署,完整记录整个开发过程。
---
## 二、开发环境
| 工具 | 版本 |
|------|------|
| OpenHarmony SDK | 23(API 11) |
| Hvigor | 6.24.2 |
| HDC | 3.2.0d |
| 目标设备 | HarmonyOS 6.1.0(ALN-AL00) |
| 开发语言 | ArkTS(ETS) |
| UI 框架 | ArkUI |
开发在 macOS 上进行,使用命令行工具链而非 IDE,这样可以更清晰地理解鸿蒙应用的构建流程。
---
## 三、项目初始化
### 3.1 创建项目
使用 DevEco Studio 创建 Empty Ability 模板项目,项目名为 `MyApplication`,包名为 `com.nutpi.myapplication`。
创建后的项目结构:
```
MyApplication/
├── AppScope/ # 应用级配置
├── entry/ # 主模块
│ ├── src/main/ets/
│ │ ├── entryability/ # Ability 入口
│ │ └── pages/ # 页面
│ ├── src/main/resources/ # 资源文件
│ └── build-profile.json5 # 模块构建配置
├── build-profile.json5 # 应用构建配置
├── hvigorfile.ts # 构建脚本
└── oh-package.json5 # 包管理
```
### 3.2 SDK 版本适配
查看 `build-profile.json5`,发现默认配置了 SDK 6.1.1(24):
```json5
{
"products": [{
"targetSdkVersion": "6.1.1(24)",
"compatibleSdkVersion": "6.1.1(24)",
}]
}
```
连接设备后发现设备运行的是 HarmonyOS **6.1.0.117**(型号 ALN-AL00),对应的 SDK 版本为 23。需要降级适配:
```json5
{
"products": [{
"targetSdkVersion": "6.1.0(23)",
"compatibleSdkVersion": "6.1.0(23)",
}]
}
```
> **踩坑经验**:如果 targetSdkVersion 高于设备 SDK 版本,hdc install 会报错 `install failed due to older sdk version in the device`。必须确保 targetSdk 与设备匹配。
---
## 四、数据模型设计
根据 ALAPI 接口的实际返回格式定义数据模型。
### 4.1 接口信息
- **地址**:`POST https://v3.alapi.cn/api/word`
- **请求头**:`Content-Type: application/json`
- **参数**:`token`(接口凭证)、`word`(要查询的汉字)
### 4.2 实际返回结构
```json
{
"success": true,
"code": 200,
"message": "success",
"data": [{
"word": "好",
"old_word": "好",
"strokes": 6,
"pinyin": "hǎo",
"radical": "女",
"explanation": "好〈形〉 (会意。从女,从子。本义美,貌美)...",
"more": "好 hao 部首 女 部首笔画 03 总笔画 06..."
}],
"time": 1780569751,
"usage": 0
}
```
### 4.3 模型定义
```typescript
export interface WordResponse {
success: boolean;
code: number;
message: string;
data: WordItemData[];
time: number;
usage: number;
}
export interface WordItemData {
word: string;
old_word: string;
strokes: number;
pinyin: string;
radical: string;
explanation: string;
more: string;
}
```
> **注意**:`data` 是数组而非单个对象,且字段名为 `radical`(单数)而非 `radicals`。组词和成语信息全部整合在 `more` 字段的纯文本中,没有独立的结构化字段。
---
## 五、网络请求模块
### 5.1 使用 @kit.NetworkKit
HarmonyOS 提供 `@kit.NetworkKit` 中的 `http` 模块用于网络请求:
```typescript
import { http } from '@kit.NetworkKit';
import { WordResponse } from '../model/WordData';
import { API_TOKEN } from './ApiConfig';
const API_URL = 'https://v3.alapi.cn/api/word';
export function queryWord(word: string): Promise<WordResponse> {
return new Promise((resolve, reject) => {
const httpRequest = http.createHttp();
httpRequest.request(
API_URL,
{
method: http.RequestMethod.POST,
header: {
'Content-Type': 'application/json',
},
extraData: JSON.stringify({
token: API_TOKEN,
word: word,
}),
connectTimeout: 15000,
readTimeout: 15000,
},
(err, data) => {
if (err) {
httpRequest.destroy();
reject(new Error(`网络请求失败: ${err.message}`));
return;
}
// 解析响应...
}
);
});
}
```
### 5.2 关键点
1. **extraData 需要序列化**:`extraData` 传入 JSON 对象时需要手动 `JSON.stringify()`,不能直接传对象字面量。
2. **回调 VS Promise**:`http.request()` 的第三个参数是回调函数,我们在回调内手动封装为 Promise。
3. **资源释放**:每次请求完成后必须调用 `httpRequest.destroy()` 释放连接。
---
## 六、API Token 安全管理
### 6.1 问题
API Token 是敏感信息,不能硬编码在代码中提交到远程仓库。
### 6.2 解决方案
创建独立的配置文件,加入 `.gitignore`:
```typescript
// ApiConfig.ets - 真实配置(被 gitignore 忽略)
export const API_TOKEN: string = '你的token';
```
```typescript
// ApiConfigTemplate.ets - 模板(可提交)
export const API_TOKEN: string = '请填入你的API token';
```
`.gitignore` 中添加:
```
**/ApiConfig.ets
```
开发者克隆项目后:
```bash
cp ApiConfigTemplate.ets ApiConfig.ets
# 编辑 ApiConfig.ets 填入真实 token
```
---
## 七、UI 实现
### 7.1 页面结构
应用采用单页面设计,包含三个状态视图:
```
┌──────────────────────┐
│ 新华字典(标题) │
├──────────────────────┤
│ [🔍 请输入汉字...] [🔍]│ ← 搜索栏
├──────────────────────┤
│ │
│ ● 初始状态:引导提示 │
│ ● 加载中:Loading │
│ ● 错误:错误信息 │
│ ● 结果:信息卡片 │
│ │
└──────────────────────┘
```
### 7.2 搜索栏实现
```typescript
Row() {
TextInput({
placeholder: '请输入要查询的汉字...',
text: this.searchWord
})
.layoutWeight(1)
.fontSize(16)
.height(48)
.backgroundColor('#f0f0f5')
.borderRadius(24)
.onChange((value) => { this.searchWord = value.trim(); })
.onSubmit(() => { this.doSearch(); })
Button() { Text('🔍').fontSize(20) }
.width(48).height(48).borderRadius(24)
.backgroundColor('#4a6cf7')
.onClick(() => { this.doSearch(); })
}
```
### 7.3 结果卡片实现
使用 `@Builder` 封装可复用的 UI 组件:
```typescript
@Builder
buildWordHeader() {
Row() {
Text(this.wordData!.word) // 大号汉字
.fontSize(56).fontWeight(FontWeight.Bold)
Column() {
Text(this.wordData!.pinyin) // 拼音
Row() { // 部首 + 笔画
Text('部首: ' + this.wordData!.radical)
Text('笔画: ' + this.wordData!.strokes + '画')
}
}
}
}
@Builder
buildSectionCard(title: string, content: string) {
Column() {
Text(title).fontSize(17).fontWeight(FontWeight.Bold)
Text(content).fontSize(14).lineHeight(22)
}
// 圆角卡片样式...
}
```
### 7.4 卡片样式设计
每张结果卡片使用白色背景、圆角 + 阴影,形成 Material Design 风格的卡片布局:
```typescript
.backgroundColor('#ffffff')
.borderRadius(16)
.padding(18)
.margin({ left: 16, right: 16, top: 8, bottom: 8 })
.shadow({
radius: 8,
color: 'rgba(0,0,0,0.06)',
offsetY: 2
})
```
### 7.5 关于 @Builder 的注意点
ArkTS 中自定义 UI 组件需要使用 `@Builder` 注解:
```typescript
@Builder // ← 必须加注解
buildWordHeader() { ... }
```
在 `build()` 中调用时需要用 `this.` 前缀:
```typescript
this.buildWordHeader() // ✅ 正确
buildWordHeader() // ❌ 编译错误:Cannot find name
```
---
## 八、网络权限配置
HarmonyOS 应用需要显式声明网络权限。在 `module.json5` 中添加:
```json5
{
"module": {
"requestPermissions": [
{
"name": "ohos.permission.INTERNET"
}
]
}
}
```
不添加此权限将导致网络请求失败。
---
## 九、构建与部署
### 9.1 构建 HAP
使用 hvigorw 命令行构建:
```bash
hvigorw assembleHap --mode module -p product=default -p buildMode=debug
```
构建产物在 `entry/build/default/outputs/default/` 目录下:
- `entry-default-signed.hap`(已签名的安装包)
- `entry-default-unsigned.hap`(未签名包)
### 9.2 安装与启动
```bash
# 查看已连接的设备
hdc list targets
# 安装 HAP
hdc install entry/build/default/outputs/default/entry-default-signed.hap
# 启动应用
hdc shell "aa start -a EntryAbility -b com.nutpi.myapplication"
```
### 9.3 查看运行时日志
```bash
hdc shell "hilog -x -L error"
```
---
## 十、遇到的坑与解决方案
### 10.1 SDK 版本不匹配
**现象**:`hdc install` 报错 `install failed due to older sdk version in the device`
**解决**:检查设备 SDK 版本,将 `build-profile.json5` 中的 targetSdkVersion 降级为设备兼容的版本。
### 10.2 extraData 格式问题
**现象**:请求成功但服务端返回异常
**解决**:`extraData` 需要 `JSON.stringify()` 序列化,同时 `Content-Type` 必须设为 `application/json`。
### 10.3 设备锁屏无法启动
**现象**:`aa start` 报错 `The device screen is locked during the application launch`
**解决**:先唤醒屏幕:`hdc shell "power-shell wakeup"`,再启动应用。或者在设备设置中关闭开发者模式。
### 10.4 组件找不到的错误
**现象**:编译报错 `UI component 'Row' cannot be used in this place`
**解决**:自定义 UI 方法需添加 `@Builder` 注解,并在 `build()` 中用 `this.` 调用。
### 10.5 HTTP 模块类型定义
**现象**:`http.RequestMethod.POST` 编译报错
**解决**:确认 SDK 版本对应的 API。SDK 23 使用 `@kit.NetworkKit`,使用 `http.RequestMethod.POST` 符合规范。
---
## 十一、项目心得
1. **命令行效率**:使用 hvigorw + hdc 命令行工具链,比 IDE 更可控,适合 CI/CD 集成。
2. **ArkUI 的声明式开发体验**:ArkUI 借鉴了声明式 UI 的思想,与 SwiftUI、Jetpack Compose 类似,学习曲线对前端/移动开发者来说相对平缓。
3. **鸿蒙 SDK 兼容性**:不同版本的 SDK 差异较大,开发前务必确认设备 API 版本。
4. **API Token 安全管理**:敏感信息必须通过配置文件管理,加入 `.gitignore`,提供模板供其他开发者参考。
---
## 十二、总结
本文完整记录了使用 ArkTS + ArkUI 开发鸿蒙新华字典应用的全过程,从环境搭建、接口对接、UI 构建到设备部署。整个项目代码量约 300 行,涵盖了一个完整鸿蒙应用的核心技术点。
虽然鸿蒙生态仍在快速演进,但 ArkTS 的开发体验已经相当成熟。随着 HarmonyOS NEXT 的推进,原生鸿蒙应用开发将成为越来越重要的技能方向。
---
## 项目地址
本文所有代码已开源:[https://gitcode.com/jianguoxu/myapplication](https://gitcode.com/jianguoxu/myapplication)
更多推荐



所有评论(0)