# HarmonyOS NEXT(API 24)实战:从零搭建旅游攻略问答 AI 应用


本文完整记录了一个基于 HarmonyOS NEXT API 24(API Version 6.1.1)的旅游攻略问答应用的开发全过程,涵盖 ArkTS 声明式 UI、网络请求、SSE 流式数据解析、AI 对话集成等核心知识点,附带完整源码与避坑指南。
一、前言
1.1 为什么选择 HarmonyOS NEXT
HarmonyOS NEXT 是华为面向万物互联时代打造的全场景智能操作系统,自 API 24(SDK 6.1.1)起已全面支持 Stage 模型与 ArkTS 语言。与传统的 Android/Linux 内核不同,HarmonyOS NEXT 采用了微内核架构,具有以下显著优势:
- 分布式能力:一套代码可运行在手机、平板、智慧屏、手表等多种设备上
- 原生安全:基于微内核的安全机制,系统服务按最小权限原则设计
- 高性能 ArkTS 运行时:ArkTS 编译为方舟字节码,性能接近原生
- 完善的 UI 框架:ArkUI 声明式框架,开发体验对标 SwiftUI / Jetpack Compose
本文所构建的应用 targetSdkVersion 为 6.1.1(24),即 API 24 版本,这是当前 HarmonyOS NEXT 的主流稳定版本。
1.2 项目背景
随着人们生活水平的提高,旅游已成为重要的休闲方式。然而,面对海量的网络信息,规划一次完美的旅行往往需要大量时间和精力。本项目的目标正是利用大语言模型的强大知识能力,构建一个"旅游攻略问答助手",让用户通过自然对话即可获得个性化的旅行建议。
1.3 技术选型
| 技术层 | 选型 | 说明 |
|---|---|---|
| 开发语言 | ArkTS | HarmonyOS 原生声明式语言 |
| UI 框架 | ArkUI | 声明式 UI,响应式状态管理 |
| 应用模型 | Stage 模型 | HarmonyOS NEXT 推荐模型 |
| 网络请求 | @kit.NetworkKit |
原生 HTTP 库,支持 SSE |
| AI 模型 | DeepSeek-V3 | GitCode API 提供的开源大模型 |
| 数据格式 | SSE (Server-Sent Events) | 服务端流式推送,实现打字机效果 |
| 构建工具 | hvigor | HarmonyOS 官方构建工具 |
| SDK 版本 | API 24 (6.1.1) | HarmonyOS NEXT 最新稳定版 |
二、项目搭建与工程结构
2.1 创建项目
使用 DevEco Studio(推荐 5.0+ 版本)创建新项目:
- 打开 DevEco Studio → Create Project
- 选择 Empty Ability 模板
- 配置项目信息:
- Project Name:
Demo022 - Bundle Name:
com.example.demo02 - Compile SDK:
6.1.1(24) - Model:
Stage - Language:
ArkTS
- Project Name:
2.2 项目目录结构
Demo022/
├── AppScope/ # 应用级配置
│ ├── app.json5 # 应用基本信息(bundleName、版本号等)
│ └── resources/base/element/
│ └── string.json # 字符串资源(应用名称等)
├── entry/ # 应用模块(entry 类型)
│ ├── build-profile.json5 # 模块构建配置
│ ├── oh-package.json5 # 模块依赖声明
│ ├── obfuscation-rules.txt # 代码混淆规则
│ ├── src/main/
│ │ ├── ets/ # ArkTS 源码目录
│ │ │ ├── AIChatService.ets # AI 聊天服务(网络请求 + SSE 解析)
│ │ │ ├── entryability/
│ │ │ │ └── EntryAbility.ets # Ability 生命周期管理
│ │ │ ├── entrybackupability/
│ │ │ │ └── EntryBackupAbility.ets # 备份扩展
│ │ │ └── pages/
│ │ │ └── Index.ets # 主页面(聊天界面)
│ │ ├── module.json5 # 模块配置文件
│ │ └── resources/base/element/
│ │ ├── color.json # 颜色资源
│ │ ├── float.json # 浮点数值资源
│ │ └── string.json # 字符串资源
│ └── hvigorfile.ts # hvigor 构建脚本
├── hvigor/
│ └── hvigor-config.json5 # hvigor 配置
├── build-profile.json5 # 全局构建配置
├── hvigorfile.ts # 根构建脚本
├── oh-package.json5 # 根依赖声明
└── local.properties # 本地开发环境配置
2.3 核心配置文件解析
全局构建配置 build-profile.json5
{
"app": {
"signingConfigs": [],
"products": [
{
"name": "default",
"signingConfig": "default",
"targetSdkVersion": "6.1.1(24)",
"compatibleSdkVersion": "6.1.1(24)",
"runtimeOS": "HarmonyOS",
"buildOption": {
"strictMode": {
"caseSensitiveCheck": true,
"useNormalizedOHMUrl": true
}
}
}
],
"buildModeSet": [
{ "name": "debug" },
{ "name": "release" }
]
},
"modules": [
{
"name": "entry",
"srcPath": "./entry",
"targets": [
{ "name": "default", "applyToProducts": ["default"] }
]
}
]
}
关键配置说明:
targetSdkVersion: "6.1.1(24)"—— 目标 SDK 版本为 API 24compatibleSdkVersion—— 兼容 SDK 版本,与 target 一致runtimeOS: "HarmonyOS"—— 运行时系统strictMode—— 严格模式,开启大小写检查和 URL 规范化
页面路由配置 module.json5
{
"module": {
"name": "entry",
"type": "entry",
"mainElement": "EntryAbility",
"deviceTypes": ["phone"],
"pages": "$profile:main_pages",
"abilities": [
{
"name": "EntryAbility",
"srcEntry": "./ets/entryability/EntryAbility.ets",
"exported": true,
"skills": [
{
"entities": ["entity.system.home"],
"actions": ["ohos.want.action.home"]
}
]
}
]
}
}
三、Ability 生命周期管理
3.1 Stage 模型简介
HarmonyOS NEXT 采用 Stage 模型作为应用开发的标准模型。Stage 模型将应用分为 Ability 和 AbilityStage 两层,每个 Ability 对应一个独立的功能单元。
EntryAbility 就是我们应用的主 Ability,其生命周期包含以下阶段:
onCreate → onWindowStageCreate → onForeground → [运行中]
↑ ↓
└────── onBackground ← onWindowStageDestroy ← onDestroy
3.2 EntryAbility 实现
import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window } from '@kit.ArkUI';
const DOMAIN = 0x0000;
export default class EntryAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
// 设置颜色模式(跟随系统)
try {
this.context.getApplicationContext()
.setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);
} catch (err) {
hilog.error(DOMAIN, 'testTag', 'Failed to set colorMode. Cause: %{public}s',
JSON.stringify(err));
}
hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate');
}
onWindowStageCreate(windowStage: window.WindowStage): void {
// 加载主页面
windowStage.loadContent('pages/Index', (err) => {
if (err.code) {
hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s',
JSON.stringify(err));
return;
}
hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.');
});
}
// ... onDestroy, onWindowStageDestroy, onForeground, onBackground
}
知识点:
setColorMode(COLOR_MODE_NOT_SET)表示跟随系统自动切换深色/浅色模式loadContent('pages/Index', callback)加载指定页面,路径与module.json5中的 pages 配置对应hilog是 HarmonyOS 的日志工具,支持领域(DOMAIN)和标签(tag)分类
四、AI 聊天服务层 — AIChatService 深度解析
AIChatService.ets 是整个应用的网络核心,负责与 AI API 的通信、SSE 流式数据解析、以及请求的生命周期管理。
4.1 接口与类型定义
// 聊天消息结构
export interface ChatMessage {
role: string; // "system" | "user" | "assistant"
content: string; // 消息内容
}
// API 请求体结构
export interface ChatCompletionRequest {
model: string;
messages: ChatMessage[];
stream: boolean; // 是否启用流式输出
max_tokens: number; // 最大输出 token 数
temperature: number; // 温度参数(0~2),控制创造性
top_p: number; // 核采样参数
frequency_penalty: number; // 频率惩罚
thinking_budget: number; // 思考预算
}
// 回调接口 — 解耦网络层与 UI 层
export interface AICallbacks {
onData: (text: string) => void; // 每次收到 token 时触发
onDone: () => void; // 流式结束时触发
onError: (errMsg: string) => void; // 发生错误时触发
}
设计思考:通过 AICallbacks 回调接口将网络请求与 UI 解耦,使得网络层可以独立测试,UI 层只需关注如何展示数据。
4.2 系统提示词 — 旅游攻略专家角色设定
系统提示词(System Prompt)是决定 AI 回答质量的关键。本项目精心设计了针对旅游场景的提示词:
const SYSTEM_PROMPT: string =
'你是一位资深的旅游攻略专家,擅长为用户提供全面、实用、个性化的旅游规划建议。' +
'你熟悉国内外各大旅游目的地,了解不同季节的旅行特点,能给出交通、住宿、美食、景点、购物等全方位建议。\n\n' +
'以下是你要遵循的原则:\n' +
'1. 先了解需求:分析用户的出行时间、天数、预算、人群和偏好\n' +
'2. 给攻略:提供目的地概览、行程推荐、交通方式、住宿推荐等\n' +
'3. 注重实用:推荐具体的景点名称、餐厅、交通工具和预算范围\n' +
'4. 融入本地特色:突出目的地独特的风土人情和隐藏玩法\n' +
'5. 温馨提示:提醒天气、签证、安全、语言、货币等实用信息\n\n' +
'请用中文回复,回答结构清晰,热情友好。';
提示词工程要点:
- 角色定义 → “资深的旅游攻略专家” 确立 AI 的身份
- 能力范围 → 明确涵盖交通、住宿、美食、景点、购物等全方位
- 行为准则 → 5 条具体原则,引导 AI 的回答结构
- 输出约束 → “用中文回复,结构清晰” 控制回复风格
4.3 SSE 流式数据解析 — 核心难点攻克
SSE(Server-Sent Events)是 AI API 常用的流式传输协议。服务器将数据以 data: <json> 格式逐行推送给客户端,每行对应一个 token 或一段内容。
SSE 协议格式示例
data: {"choices":[{"delta":{"content":"你"}}]}
data: {"choices":[{"delta":{"content":"好"}}]}
data: {"choices":[{"delta":{"content":"!"}}]}
data: [DONE]
逐行解析器 parseSSEDataLine
function parseSSEDataLine(line: string): string | null {
const jsonStr = line.slice(5).trim(); // 去掉 "data:" 前缀
if (!jsonStr) return null;
try {
const parsed = JSON.parse(jsonStr) as Record<string, Object>;
const choices = parsed.choices as Object[];
if (choices && choices.length > 0) {
const choice = choices[0] as Record<string, Object>;
// 流式格式使用 delta,非流式使用 message
const delta = choice.delta as Record<string, Object>;
if (delta) return delta.content as string;
const message = choice.message as Record<string, Object>;
if (message) return message.content as string;
}
} catch (_) { /* 跳过解析失败的行 */ }
return null;
}
关键实现细节:
line.slice(5)精确去掉前 5 个字符data:JSON.parse解析 JSON 字符串- 同时兼容
delta(流式)和message(非流式)两种格式 try-catch捕获解析异常,防止单行错误影响后续处理
完整响应体解析 parseFullSSEBody
当底层网络库不支持逐事件触发时,需要从完整响应体中提取所有 SSE 行:
function parseFullSSEBody(body: string): string {
let result = '';
const lines = body.split('\n');
for (const line of lines) {
const trimmed = line.trim();
if (trimmed.startsWith('data:')) {
if (trimmed === 'data:[DONE]') break; // 结束标记
const content = parseSSEDataLine(trimmed);
if (content) result += content;
}
}
return result;
}
4.4 网络请求核心 — queryAI 函数
export function queryAI(
callbacks: AICallbacks,
messages: ChatMessage[],
): void {
// 1. 取消上一次未完成的请求
if (httpRequestTask) {
httpRequestTask.destroy();
httpRequestTask = null;
}
const httpRequest = http.createHttp();
httpRequestTask = httpRequest;
// 2. 构建请求体(合并 system prompt)
const fullMessages: ChatMessage[] = [
{ role: 'system', content: SYSTEM_PROMPT },
...messages,
];
const requestBody: ChatCompletionRequest = {
model: 'deepseek-ai/DeepSeek-V3',
messages: fullMessages,
stream: true,
max_tokens: 2048,
temperature: 0.6,
top_p: 0.95,
frequency_penalty: 0,
thinking_budget: 2048,
};
// 3. 状态标记
let isDone = false;
let receivedAnyData = false;
let buffer = '';
// 4. 注册 dataReceive 事件(SSE 流式接收)
httpRequest.on('dataReceive', (data: ArrayBuffer) => {
const text = arrayBufferToString(data);
buffer += text;
receivedAnyData = true;
const lines = buffer.split('\n');
buffer = lines.pop() ?? ''; // 最后一行可能不完整
for (const line of lines) {
const trimmed = line.trim();
if (!trimmed.startsWith('data:')) continue;
if (trimmed === 'data:[DONE]') {
if (!isDone) { isDone = true; callbacks.onDone(); }
continue;
}
const content = parseSSEDataLine(trimmed);
if (content) callbacks.onData(content);
}
});
// 5. dataEnd 事件
httpRequest.on('dataEnd', () => {
if (!isDone) { isDone = true; callbacks.onDone(); }
httpRequestTask = null;
});
// 6. 发起 POST 请求
httpRequest.request(
API_URL,
{
method: http.RequestMethod.POST,
header: {
Authorization: `Bearer ${API_KEY}`,
'Content-Type': 'application/json',
Accept: 'text/event-stream', // 告知服务器需要 SSE
},
extraData: JSON.stringify(requestBody),
connectTimeout: 30000, // 连接超时 30s
readTimeout: 120000, // 读取超时 120s
},
(err, resp) => {
// 错误处理 + 非流式回退逻辑(见下文)
},
);
}
4.5 非流式回退机制 — 兼容性保障
HarmonyOS NEXT 的 http 模块在不同版本中对 SSE 的支持表现不一致。部分版本的 dataReceive 事件可能不会被触发。为此,我们实现了完善的非流式回退机制:
// 在 request 回调中,如果 dataReceive 从未触发过
if (!receivedAnyData && resp.result) {
const bodyStr = typeof resp.result === 'string'
? resp.result
: arrayBufferToString(resp.result as ArrayBuffer);
// 优先解析 SSE 格式(兼容流式但未触发事件的情况)
const sseContent = parseFullSSEBody(bodyStr);
if (sseContent) {
callbacks.onData(sseContent);
} else {
// 回退到 JSON 格式
const jsonContent = parseNonStreamingBody(bodyStr);
if (jsonContent) {
callbacks.onData(jsonContent);
} else {
callbacks.onError(`无法解析响应: ${preview}`);
return;
}
}
if (!isDone) { isDone = true; callbacks.onDone(); }
}
三层回退策略:
- 首选 →
dataReceive事件逐 token 推送(最佳体验,打字机效果) - 次选 → 完整响应按 SSE 格式解析(兼容流式响应)
- 兜底 → 按非流式 JSON 解析(兼容标准 JSON 响应)
4.6 请求取消机制
export function cancelAI(): void {
if (httpRequestTask) {
httpRequestTask.destroy();
httpRequestTask = null;
}
}
每次发起新请求前也会自动取消上一次请求,避免多个请求并行导致消息错乱。
五、页面 UI 实现 — Index.ets
5.1 声明式 UI 设计理念
ArkUI 采用声明式 UI 范式,开发者只需描述"UI 应该是什么样子",框架自动处理状态变化后的界面更新。
核心概念:
- @State 装饰器:标记响应式状态变量,状态变化时自动触发界面重绘
- @Builder 装饰器:定义可复用的 UI 片段
- @Entry 装饰器:标记页面入口
- @Component 装饰器:定义可复用的组件
5.2 页面结构总览
Column (根容器)
├── Row (顶部标题栏) ── Text("🗺️ 旅游攻略问答")
├── Scroll (聊天列表)
│ └── Column
│ ├── ForEach → MessageBubble(item) ── 用户/AI 消息气泡
│ ├── [if isLoading && currentAIResponse] → AIBubble() ── 流式内容
│ └── [if isLoading && !currentAIResponse] → LoadingIndicator() ── 等待动效
└── Row (底部输入区)
├── TextInput (文本输入框)
├── Blank (间距)
└── Button (发送/取消按钮)
5.3 状态管理
@State messages: MessageItem[] = [ /* 初始欢迎消息 */ ];
@State inputText: string = '';
@State isLoading: boolean = false;
@State currentAIResponse: string = '';
四个 @State 变量控制整个页面的渲染:
messages— 聊天历史消息列表,每次 push 新消息自动刷新 UIinputText— 输入框文本,控制发送按钮的启用状态isLoading— 请求状态,控制 loading 显示和按钮交互currentAIResponse— 当前流式回复内容,实时追加显示
5.4 消息气泡组件 (@Builder)
用户消息(绿色右对齐)
if (item.role === 'user') {
Blank() // 占位,使气泡靠右
Column() {
Text(item.content)
.fontSize(15)
.fontColor('#333333')
.lineHeight(22)
}
.padding({ left: 14, right: 14, top: 10, bottom: 10 })
.backgroundColor('#95EC69') // 绿色背景
.borderRadius({
topLeft: 16, topRight: 4, // 右上角小圆角(气泡尾巴效果)
bottomLeft: 16, bottomRight: 16
})
.constraintSize({ maxWidth: '75%' })
.margin({ bottom: 10 })
}
设计细节:
- 使用
Blank()占位实现靠右布局 borderRadius非对称圆角营造"气泡对话"的视觉风格constraintSize({ maxWidth: '75%' })限制气泡最大宽度- 颜色
#95EC69是典型的聊天应用用户气泡绿
AI 消息(白色左对齐,带头像)
Column() {
Row() {
Text('🤖').fontSize(18)
Text(' 攻略助手').fontSize(12).fontColor('#999999')
}
.margin({ bottom: 6 })
Text(item.content)
.fontSize(15).fontColor('#333333').lineHeight(22)
}
.padding({ left: 14, right: 14, top: 10, bottom: 10 })
.backgroundColor('#FFFFFF')
.borderRadius({
topLeft: 4, topRight: 16, // 左上角小圆角
bottomLeft: 16, bottomRight: 16
})
.constraintSize({ maxWidth: '80%' })
5.5 流式加载状态设计
三种状态的处理:
// 在 Scroll 的 Column 内部
if (this.isLoading) {
if (this.currentAIResponse) {
// 已有内容 → 流式打字效果
this.AIBubble(this.currentAIResponse)
} else {
// 等待中 → Loading 动画
this.LoadingIndicator()
}
}
Loading 动画组件:
@Builder LoadingIndicator() {
Row() {
Column() {
Row() {
Text('🤖').fontSize(18)
Text(' 攻略助手').fontSize(12).fontColor('#999999')
}
.margin({ bottom: 8 })
Row() {
LoadingProgress() // HarmonyOS 原生加载动画
.width(24).height(24)
.color('#FF6B35') // 橙色主题色
Text(' 正在思考旅行方案...')
.fontSize(14).fontColor('#999999')
}
}
.padding({ left: 14, right: 14, top: 10, bottom: 10 })
.backgroundColor('#FFFFFF')
.borderRadius(...)
}
}
5.6 发送按钮的交互状态
Button() {
if (this.isLoading) {
LoadingProgress()
.width(22).height(22).color('#FFFFFF')
} else {
Image($r('app.media.startIcon'))
.width(22).height(22).objectFit(ImageFit.Contain)
}
}
.backgroundColor(
this.inputText.trim() && !this.isLoading ? '#FF6B35' : '#CCCCCC'
)
.enabled(!!this.inputText.trim() && !this.isLoading)
.onClick(() => {
if (this.isLoading) {
// 取消请求
cancelAI();
this.isLoading = false;
this.currentAIResponse = '';
} else {
this.sendMessage();
}
})
三种状态:
- 空闲 + 有输入 → 橙色按钮,可点击发送
- 空闲 + 无输入 → 灰色按钮,禁用
- 加载中 → 显示 LoadingProgress,点击可取消请求
5.7 发送消息流程
sendMessage(): void {
const text = this.inputText.trim();
if (!text || this.isLoading) return;
// 1. 添加用户消息到列表
this.messages.push({ role: 'user', content: text });
this.inputText = '';
// 2. 滚动到底部
setTimeout(() => {
this.scroller.scrollEdge(Edge.Bottom);
}, 100);
// 3. 准备 AI 请求
this.isLoading = true;
this.currentAIResponse = '';
// 4. 构建历史消息(不含 system prompt)
const chatHistory: ChatMessage[] = this.messages.map<ChatMessage>((m) => ({
role: m.role,
content: m.content,
}));
// 5. 调用 AI
queryAI(
{
onData: (text: string) => {
this.currentAIResponse += text; // 追加到流式缓冲区
this.scroller.scrollEdge(Edge.Bottom); // 自动滚屏
},
onDone: () => {
// 流式完成,将完整回复加入消息列表
if (this.currentAIResponse) {
this.messages.push({ role: 'assistant', content: this.currentAIResponse });
}
this.isLoading = false;
this.currentAIResponse = '';
},
onError: (errMsg: string) => {
this.messages.push({ role: 'assistant', content: '😅 抱歉,出错了:' + errMsg });
this.isLoading = false;
this.currentAIResponse = '';
},
},
chatHistory,
);
}
关键点:
- 使用
setTimeout延迟滚动,确保 DOM 更新完成后才滚动 map<ChatMessage>()显式指定泛型类型,满足 ArkTS 严格类型检查onDone中将流式内容currentAIResponse整体加入消息列表,而非逐 token 加入
六、ArkTS 严格模式与常见编译错误
API 24 引入了更严格的编译检查(arkts-no-untyped-obj-literals 等),以下是开发过程中遇到的典型错误及解决方案:
6.1 arkts-no-untyped-obj-literals
错误:对象字面量必须对应显式声明的类或接口
// ❌ 错误写法
const chatHistory = this.messages.map((m) => ({
role: m.role,
content: m.content,
}));
// ✅ 正确写法 — 使用泛型指定类型
const chatHistory: ChatMessage[] = this.messages.map<ChatMessage>((m) => ({
role: m.role,
content: m.content,
}));
6.2 maxWidth 在 ColumnAttribute 上不存在
错误:ArkUI 的 Column 组件属性链中不包含 maxWidth 方法
// ❌ 错误写法
Column() { /* ... */ }
.maxWidth('75%')
// ✅ 正确写法 — 使用 constraintSize
Column() { /* ... */ }
.constraintSize({ maxWidth: '75%' })
constraintSize 是一个通用的尺寸约束属性,可同时设置 minWidth、maxWidth、minHeight、maxHeight。
6.3 on 方法已弃用
// 当前写法(可用但产生警告)
httpRequest.on('dataReceive', callback);
// 建议改为(API 24+ 推荐)
// httpRequest.on('dataReceive', callback);
// 新版本中应使用事件监听器的替代 API
七、性能优化与最佳实践
7.1 网络请求优化
- 连接复用:通过
http.createHttp()创建实例后复用,而不是每次请求都创建新的 - 超时配置:
connectTimeout: 30s,readTimeout: 120s,避免长时间等待 - 请求取消:每次新请求前取消上一次,防止回调错乱和资源泄漏
7.2 UI 渲染优化
- 条件渲染:使用
if条件语句而非Visibility属性控制组件显示,减少组件树的复杂度和内存占用 - ForEach key:
ForEach的第三个参数(item, index) => index.toString()提供唯一 key,帮助框架高效复用和更新节点 - 延迟滚动:状态更新后使用
setTimeout延迟50-100ms再执行滚动,确保布局完成后再触发
7.3 内存管理
- 组件资源释放:在
onPageHide或组件销毁时调用cancelAI()取消进行中的网络请求 - 流式缓冲区清空:
onDone和onError回调中将currentAIResponse置空,不保留过期数据
7.4 ArkTS 编码规范
- 显式类型声明:所有变量和函数参数都添加类型注解,避免依赖类型推断
- 接口先行:先定义接口(如
ChatMessage、AICallbacks),再基于接口实现逻辑 - 模块化拆分:将网络层
AIChatService与 UI 层Index.ets分离,降低耦合
八、项目部署与测试
8.1 构建命令
# 开发调试构建
hvigorw assembleHap --mode module -p module=entry@default -p product=default
# 生产构建
hvigorw assembleHap --mode module -p module=entry@release -p product=default
8.2 真机调试
- 使用 USB 连接 HarmonyOS 设备
- DevEco Studio 中点击 Run 按钮
- 或使用命令行:
hdc install entry/build/default/outputs/default/entry-default-unsigned.hap
8.3 常见问题排查
| 问题 | 原因 | 解决方案 |
|---|---|---|
on has been deprecated |
httpRequest.on() API 弃用 |
可忽略(兼容旧 API) |
| INTERNET 权限警告 | 未配置网络权限 | 在 module.json5 中添加 ohos.permission.INTERNET |
| 签名警告 | 未配置签名 | 开发阶段可忽略,发布前在 build-profile.json5 中配置 |
| SSE 不触发 | HarmonyOS 版本兼容性 | 非流式回退机制自动处理 |
| 编译失败: 对象字面量 | ArkTS 严格模式 | 添加泛型注解 |
九、总结与展望
9.1 项目亮点
- 完整的 AI 对话应用闭环:从 Ability 生命周期、网络请求、SSE 流式解析到 UI 呈现,覆盖了 HarmonyOS 应用开发的全链路
- 专业级提示词工程:5 条旅游攻略原则,确保 AI 输出的专业性和实用性
- 健壮的容错机制:三层 SSE 解析回退策略,兼容不同 HarmonyOS 版本的网络行为差异
- 优雅的交互设计:气泡对话、流式打字效果、加载动效、自动滚屏等,提供类即时通讯的流畅体验
- 声明式 UI 实践:基于 ArkUI 的 @State + @Builder 模式,代码简洁且易于维护
9.2 可扩展方向
- 多轮上下文理解:当前已支持多轮对话历史传递,可进一步优化上下文窗口管理
- 图片/位置分享:利用 HarmonyOS 的分布式能力,支持分享景点图片和地图位置
- 离线知识库:集成本地旅游知识库,在无网络时也能提供基础攻略
- 多设备协同:利用 HarmonyOS 分布式技术,手机规划 → 手表查看行程 → 平板展示地图
- 语音交互:集成
@kit.VoiceKit,支持语音输入旅游问题
9.3 写在最后
HarmonyOS NEXT 的 ArkTS 语言和 ArkUI 框架为应用开发带来了现代化的声明式编程体验。通过本项目,我们不仅掌握了一个完整的 AI 聊天应用的开发流程,更深入理解了 HarmonyOS 的网络编程、状态管理、类型系统等核心概念。希望本文能为正在学习 HarmonyOS 开发的你提供有价值的参考。
完整项目源码已在本地可用,欢迎在此基础上进行二次开发和创新!
本文基于 HarmonyOS NEXT API 24(SDK 6.1.1)编写,于 2026 年 6 月完成。API 和 SDK 版本更新后部分接口可能发生变化,请以官方文档为准。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)