鸿蒙应用开发实战指南:构建网络数据列表应用

前言:本文从零开始,详细介绍如何使用HarmonyOS ArkTS语言开发一个具备网络请求和数据列表展示功能的应用。涵盖工程搭建、网络封装、UI开发、错误处理等核心知识点,适合鸿蒙开发入门者学习参考。
一、开发环境准备
1.1 必备软件清单
| 软件 | 版本要求 | 用途 | 下载地址 |
|---|---|---|---|
| Node.js | 16.x+ | JavaScript运行环境 | nodejs.org |
| DevEco Studio | 4.0+ | 鸿蒙官方IDE | developer.huawei.com |
| Git | 最新版 | 版本控制工具 | git-scm.com |
1.2 Git全局配置
bash
# 配置用户信息
git config --global user.name "YourName"
git config --global user.email "your.email@example.com"
# 配置默认分支名
git config --global init.defaultBranch main
# 配置凭证缓存(避免频繁输入密码)
git config --global credential.helper store
1.3 代码仓库创建
在Gitee/AtomGit等平台创建新仓库:
仓库配置建议:
- 仓库名:
harmonyos-network-demo - 可见性:公开
- 许可证:MIT
- 初始化选项:添加README、.gitignore(选择OpenHarmony模板)
1.4 本地仓库初始化
bash
# 克隆仓库
git clone https://gitee.com/your-username/harmonyos-network-demo.git
cd harmonyos-network-demo
# 或本地初始化后关联远程
git init
git add .
git commit -m "chore: 初始化鸿蒙网络请求示例项目"
git branch -M main
git remote add origin https://gitee.com/your-username/harmonyos-network-demo.git
git push -u origin main
二、工程创建与目录结构
2.1 创建鸿蒙工程
- 打开DevEco Studio,点击「Create Project」
- 选择「Empty Ability」模板
- 配置工程信息:
- 工程名:
HarmonyoNetworkList - 包名:
com.example.networklist - 保存位置:选择刚才克隆的仓库目录
- SDK版本:API 10+
- 设备类型:Phone
- 工程名:
2.2 推荐目录结构
HarmonyoNetworkList/
├── entry/
│ └── src/
│ └── main/
│ ├── ets/ # ArkTS源码目录
│ │ ├── entryability/ # Ability入口
│ │ ├── pages/ # 页面目录
│ │ ├── model/ # 数据模型
│ │ ├── utils/ # 工具类
│ │ └── common/ # 公共资源
│ │ ├── constants/ # 常量定义
│ │ └── styles/ # 样式配置
│ ├── resources/ # 资源文件
│ │ ├── base/ # 基础资源
│ │ │ ├── element/ # 元素资源
│ │ │ ├── media/ # 媒体资源
│ │ │ └── profile/ # 配置文件
│ │ └── rawfile/ # 原始文件
│ └── module.json5 # 模块配置
├── oh-package.json5 # 依赖管理
├── build-profile.json5 # 构建配置
└── app.json5 # 应用配置
三、核心配置文件详解
3.1 依赖管理(oh-package.json5)
json5
{
"name": "entry",
"version": "1.0.1",
"description": "HarmonyOS网络请求与列表展示示例",
"main": "",
"author": "",
"license": "MIT",
"dependencies": {},
"devDependencies": {
"@ohos/hypium": "1.0.16"
}
}
3.2 模块配置(module.json5)
json5
{
"module": {
"name": "entry",
"type": "entry",
"description": "$string:module_desc",
"mainElement": "EntryAbility",
"deviceTypes": [
"default",
"tablet"
],
"deliveryWithInstall": true,
"installationFree": false,
"pages": "$profile:main_pages",
"abilities": [
{
"name": "EntryAbility",
"srcEntry": "./ets/entryability/EntryAbility.ets",
"description": "$string:EntryAbility_desc",
"icon": "$media:app_icon",
"label": "$string:EntryAbility_label",
"startWindowIcon": "$media:icon",
"startWindowBackground": "$color:start_window_background",
"exported": true,
"skills": [
{
"entities": [
"entity.system.home"
],
"actions": [
"action.system.home"
]
}
]
}
],
"requestPermissions": [
{
"name": "ohos.permission.INTERNET",
"reason": "$string:internet_permission_reason",
"usedScene": {
"abilities": [
"EntryAbility"
],
"when": "inuse"
}
}
]
}
}
3.3 页面路由配置(main_pages.json)
json5
{
"src": [
"pages/TaskListPage"
]
}
3.4 应用级配置(app.json5)
json5
{
"app": {
"bundleName": "com.example.networklist",
"vendor": "example",
"versionCode": 1000000,
"versionName": "1.0.0",
"icon": "$media:app_icon",
"label": "$string:app_name",
"description": "$string:app_description",
"targetSDKVersion": 10,
"apiReleaseType": "Release"
}
}
3.5 字符串资源配置
json5
// resources/base/element/string.json
{
"string": [
{
"name": "app_name",
"value": "任务清单"
},
{
"name": "app_description",
"value": "基于HarmonyOS的网络请求与列表展示示例"
},
{
"name": "module_desc",
"value": "网络请求与数据列表示例模块"
},
{
"name": "EntryAbility_desc",
"value": "任务清单应用入口"
},
{
"name": "EntryAbility_label",
"value": "任务清单"
},
{
"name": "internet_permission_reason",
"value": "需要网络权限以获取任务数据"
},
{
"name": "loading_text",
"value": "加载中..."
},
{
"name": "error_text",
"value": "加载失败,请重试"
},
{
"name": "retry_text",
"value": "重试"
},
{
"name": "empty_text",
"value": "暂无数据"
}
]
}
3.6 颜色资源配置
json5
// resources/base/element/color.json
{
"color": [
{
"name": "start_window_background",
"value": "#FFFFFF"
},
{
"name": "primary_color",
"value": "#0A59F7"
},
{
"name": "background_color",
"value": "#F5F5F5"
},
{
"name": "card_background",
"value": "#FFFFFF"
},
{
"name": "text_primary",
"value": "#182431"
},
{
"name": "text_secondary",
"value": "#99182431"
},
{
"name": "divider_color",
"value": "#E5E5E5"
},
{
"name": "success_color",
"value": "#00C853"
},
{
"name": "error_color",
"value": "#FF5252"
}
]
}
四、数据模型定义
4.1 任务数据模型
typescript
// entry/src/main/ets/model/TaskModel.ets
/**
* 任务数据项模型
*/
export interface TaskItem {
id: number; // 任务ID
title: string; // 任务标题
completed: boolean; // 完成状态
userId: number; // 用户ID
}
/**
* 网络响应基类
*/
export interface ApiResponse<T> {
data: T; // 响应数据
code: number; // 响应码
message: string; // 响应消息
}
/**
* 列表响应数据
*/
export interface ListResponse<T> {
items: T[]; // 数据列表
total: number; // 总数量
page: number; // 当前页码
pageSize: number; // 每页大小
}
4.2 常量定义
typescript
// entry/src/main/ets/common/constants/ApiConstants.ets
/**
* API常量定义
*/
export class ApiConstants {
// 基础URL
private static readonly BASE_URL = 'https://jsonplaceholder.typicode.com';
// API端点
static readonly TASKS_ENDPOINT = '/todos';
static readonly TASK_DETAIL_ENDPOINT = (id: number) => `/todos/${id}`;
static readonly USER_TASKS_ENDPOINT = (userId: number) => `/todos?userId=${userId}`;
// 完整URL构建
static getFullUrl(endpoint: string): string {
return `${this.BASE_URL}${endpoint}`;
}
// 超时时间(毫秒)
static readonly CONNECT_TIMEOUT = 10000;
static readonly READ_TIMEOUT = 15000;
}
/**
* 业务常量
*/
export class BusinessConstants {
// 每页加载数量
static readonly PAGE_SIZE = 20;
// 状态码
static readonly SUCCESS_CODE = 200;
static readonly ERROR_CODE = -1;
// 缓存时间(秒)
static readonly CACHE_DURATION = 300;
}
五、网络请求封装
5.1 HTTP请求工具类
typescript
// entry/src/main/ets/utils/HttpUtil.ets
import http from '@ohos.net.http';
import { BusinessConstants } from '../common/constants/ApiConstants';
/**
* HTTP请求配置
*/
interface RequestConfig {
method?: http.RequestMethod;
header?: Record<string, string>;
readTimeout?: number;
connectTimeout?: number;
extraData?: string | Object | ArrayBuffer;
}
/**
* HTTP响应数据
*/
interface HttpResponse<T> {
data: T;
statusCode: number;
headers: Record<string, string>;
}
/**
* HTTP请求工具类
*/
export class HttpUtil {
/**
* GET请求
* @param url 请求地址
* @param params 请求参数
* @param config 请求配置
*/
static async get<T>(
url: string,
params?: Record<string, string>,
config?: RequestConfig
): Promise<HttpResponse<T>> {
// 构建带参数的URL
let fullUrl = url;
if (params && Object.keys(params).length > 0) {
const queryString = Object.keys(params)
.map(key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`)
.join('&');
fullUrl = `${url}?${queryString}`;
}
return this.request<T>(fullUrl, {
method: http.RequestMethod.GET,
readTimeout: BusinessConstants.CONNECT_TIMEOUT,
connectTimeout: BusinessConstants.READ_TIMEOUT,
...config
});
}
/**
* POST请求
* @param url 请求地址
* @param data 请求数据
* @param config 请求配置
*/
static async post<T>(
url: string,
data?: Object | string,
config?: RequestConfig
): Promise<HttpResponse<T>> {
return this.request<T>(url, {
method: http.RequestMethod.POST,
extraData: data,
readTimeout: BusinessConstants.READ_TIMEOUT,
connectTimeout: BusinessConstants.CONNECT_TIMEOUT,
...config
});
}
/**
* 通用请求方法
* @param url 请求地址
* @param config 请求配置
*/
private static async request<T>(
url: string,
config: RequestConfig = {}
): Promise<HttpResponse<T>> {
// 创建HTTP请求对象
const httpRequest = http.createHttp();
try {
// 设置默认请求头
const defaultHeaders: Record<string, string> = {
'Content-Type': 'application/json',
'Accept': 'application/json'
};
// 合并请求头
const headers = {
...defaultHeaders,
...config.header
};
// 发起请求
const response = await httpRequest.request(url, {
method: config.method || http.RequestMethod.GET,
header: headers,
readTimeout: config.readTimeout || 15000,
connectTimeout: config.connectTimeout || 10000,
extraData: config.extraData
});
// 解析响应数据
let responseData: T;
const contentType = response.headers?.['Content-Type'] || '';
const responseType = response.responseType;
switch (responseType) {
case http.HttpResponseType.STRING:
if (contentType.includes('application/json')) {
responseData = JSON.parse(response.result as string) as T;
} else {
responseData = response.result as T;
}
break;
case http.HttpResponseType.ARRAY_BUFFER:
responseData = response.result as T;
break;
default:
responseData = response.result as T;
}
return {
data: responseData,
statusCode: response.responseCode,
headers: response.headers
};
} catch (error) {
throw new Error(`请求失败: ${error.message || error}`);
} finally {
// 销毁请求对象
httpRequest.destroy();
}
}
}
5.2 任务数据服务
typescript
// entry/src/main/ets/utils/TaskService.ets
import { HttpUtil } from './HttpUtil';
import { TaskItem } from '../model/TaskModel';
import { ApiConstants } from '../common/constants/ApiConstants';
/**
* 任务数据服务类
*/
export class TaskService {
/**
* 获取所有任务列表
*/
static async getAllTasks(): Promise<TaskItem[]> {
const url = ApiConstants.getFullUrl(ApiConstants.TASKS_ENDPOINT);
const response = await HttpUtil.get<TaskItem[]>(url);
return response.data;
}
/**
* 获取单个任务详情
* @param taskId 任务ID
*/
static async getTaskDetail(taskId: number): Promise<TaskItem> {
const url = ApiConstants.getFullUrl(ApiConstants.TASK_DETAIL_ENDPOINT(taskId));
const response = await HttpUtil.get<TaskItem>(url);
return response.data;
}
/**
* 获取指定用户的任务
* @param userId 用户ID
*/
static async getUserTasks(userId: number): Promise<TaskItem[]> {
const url = ApiConstants.getFullUrl(ApiConstants.USER_TASKS_ENDPOINT(userId));
const response = await HttpUtil.get<TaskItem[]>(url);
return response.data;
}
/**
* 按完成状态筛选任务
* @param completed 是否完成
*/
static async getTasksByStatus(completed: boolean): Promise<TaskItem[]> {
const url = ApiConstants.getFullUrl(ApiConstants.TASKS_ENDPOINT);
const response = await HttpUtil.get<TaskItem[]>(url, { completed: String(completed) });
return response.data;
}
}
六、UI组件开发
6.1 任务列表页面
typescript
// entry/src/main/ets/pages/TaskListPage.ets
import { TaskItem } from '../model/TaskModel';
import { TaskService } from '../utils/TaskService';
import promptAction from '@ohos.promptAction';
/**
* 任务状态枚举
*/
enum LoadState {
IDLE = 'idle',
LOADING = 'loading',
SUCCESS = 'success',
ERROR = 'error'
}
/**
* 任务列表页面
*/
@Entry
@Component
struct TaskListPage {
// 任务列表数据
@State private taskList: TaskItem[] = [];
// 加载状态
@State private loadState: LoadState = LoadState.IDLE;
// 错误信息
@State private errorMessage: string = '';
// 是否正在下拉刷新
@State private isRefreshing: boolean = false;
/**
* 页面即将出现时加载数据
*/
aboutToAppear(): void {
this.loadTaskData();
}
/**
* 加载任务数据
*/
private async loadTaskData(): Promise<void> {
this.loadState = LoadState.LOADING;
this.errorMessage = '';
try {
const tasks = await TaskService.getAllTasks();
this.taskList = tasks;
this.loadState = LoadState.SUCCESS;
} catch (error) {
this.errorMessage = error.message || '加载失败,请重试';
this.loadState = LoadState.ERROR;
console.error(`[TaskListPage] 加载失败: ${this.errorMessage}`);
}
}
/**
* 下拉刷新
*/
private async onRefresh(): Promise<void> {
this.isRefreshing = true;
await this.loadTaskData();
this.isRefreshing = false;
}
/**
* 重试加载
*/
private onRetry(): void {
this.loadTaskData();
}
/**
* 任务项点击事件
*/
private onTaskClick(task: TaskItem): void {
promptAction.showToast({
message: `任务: ${task.title}\n状态: ${task.completed ? '已完成' : '进行中'}`,
duration: 2000
});
}
/**
* 切换任务完成状态
*/
private toggleTaskStatus(task: TaskItem): void {
task.completed = !task.completed;
// 更新UI
const index = this.taskList.findIndex(item => item.id === task.id);
if (index !== -1) {
this.taskList.splice(index, 1, { ...task });
}
}
/**
* 构建加载中UI
*/
@Builder
private LoadingBuilder() {
Column() {
LoadingProgress()
.width(48)
.height(48)
.color($r('app.color.primary_color'))
Text($r('app.string.loading_text'))
.fontSize(16)
.fontColor($r('app.color.text_secondary'))
.margin({ top: 16 })
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
/**
* 构建错误UI
*/
@Builder
private ErrorBuilder() {
Column({ space: 16 }) {
Image($r('app.media.ic_error'))
.width(80)
.height(80)
.fillColor($r('app.color.error_color'))
Text(this.errorMessage || $r('app.string.error_text'))
.fontSize(16)
.fontColor($r('app.color.text_secondary'))
.textAlign(TextAlign.Center)
Button($r('app.string.retry_text'))
.onClick(() => this.onRetry())
.type(ButtonType.Capsule)
.backgroundColor($r('app.color.primary_color'))
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
.padding(24)
}
/**
* 构建空数据UI
*/
@Builder
private EmptyBuilder() {
Column({ space: 16 }) {
Image($r('app.media.ic_empty'))
.width(120)
.height(120)
.fillColor($r('app.color.text_secondary'))
Text($r('app.string.empty_text'))
.fontSize(16)
.fontColor($r('app.color.text_secondary'))
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
/**
* 构建任务项UI
*/
@Builder
private TaskItemBuilder(task: TaskItem, index: number) {
Row() {
// 状态图标
Image(task.completed ? $r('app.media.ic_check_circle') : $r('app.media.ic_radio_unchecked'))
.width(24)
.height(24)
.fillColor(task.completed ? $r('app.color.success_color') : $r('app.color.text_secondary'))
.margin({ right: 12 })
// 任务信息
Column({ space: 4 }) {
Text(task.title)
.fontSize(16)
.fontColor($r('app.color.text_primary'))
.maxLines(2)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.decoration({
type: task.completed ? TextDecorationType.LineThrough : TextDecorationType.None
})
Text(`ID: ${task.id} | 用户: ${task.userId}`)
.fontSize(12)
.fontColor($r('app.color.text_secondary'))
}
.alignItems(HorizontalAlign.Start)
.layoutWeight(1)
// 箭头图标
Image($r('app.media.ic_arrow_right'))
.width(16)
.height(16)
.fillColor($r('app.color.text_secondary'))
}
.width('100%')
.padding(16)
.backgroundColor($r('app.color.card_background'))
.borderRadius(8)
.margin({ bottom: 8 })
.onClick(() => this.onTaskClick(task))
.gesture(
LongPressGesture({ repeat: false })
.onAction(() => {
this.toggleTaskStatus(task);
})
)
}
/**
* 构建页面UI
*/
build() {
Column() {
// 标题栏
Row() {
Text('任务清单')
.fontSize(20)
.fontWeight(FontWeight.Bold)
.fontColor($r('app.color.text_primary'))
}
.width('100%')
.height(56)
.padding({ left: 16, right: 16 })
.backgroundColor($r('app.color.card_background'))
// 内容区域
if (this.loadState === LoadState.LOADING) {
this.LoadingBuilder()
} else if (this.loadState === LoadState.ERROR) {
this.ErrorBuilder()
} else if (this.taskList.length === 0) {
this.EmptyBuilder()
} else {
// 任务列表
List({ space: 0 }) {
ForEach(this.taskList, (task: TaskItem, index: number) => {
ListItem() {
this.TaskItemBuilder(task, index)
}
}, (task: TaskItem) => task.id.toString())
}
.width('100%')
.layoutWeight(1)
.padding({ left: 16, right: 16, top: 8 })
.scrollBar(BarState.Auto)
.edgeEffect(EdgeEffect.Spring)
}
// 统计信息
if (this.loadState === LoadState.SUCCESS && this.taskList.length > 0) {
Row() {
Text(`共 ${this.taskList.length} 条任务`)
.fontSize(14)
.fontColor($r('app.color.text_secondary'))
Blank()
Text(`已完成: ${this.taskList.filter(t => t.completed).length}`)
.fontSize(14)
.fontColor($r('app.color.success_color'))
}
.width('100%')
.height(48)
.padding({ left: 16, right: 16 })
.backgroundColor($r('app.color.card_background'))
}
}
.width('100%')
.height('100%')
.backgroundColor($r('app.color.background_color'))
}
}
6.2 样式配置类
typescript
// entry/src/main/ets/common/styles/AppStyles.ets
/**
* 应用样式配置
*/
export class AppStyles {
// 间距
static readonly SPACING = {
XS: 4,
SM: 8,
MD: 12,
LG: 16,
XL: 20,
XXL: 24
};
// 字体大小
static readonly FONT_SIZE = {
XS: 12,
SM: 14,
MD: 16,
LG: 18,
XL: 20,
XXL: 24
};
// 圆角
static readonly RADIUS = {
SM: 4,
MD: 8,
LG: 12,
XL: 16,
CIRCLE: 999
};
// 阴影
static readonly SHADOW = {
SM: {
radius: 4,
color: '#1A000000',
offsetX: 0,
offsetY: 2
},
MD: {
radius: 8,
color: '#1A000000',
offsetX: 0,
offsetY: 4
},
LG: {
radius: 16,
color:'#1A000000',
offsetX: 0,
offsetY: 8
}
};
}
七、常见问题与解决方案
7.1 网络请求相关
问题1:网络请求失败提示权限不足
错误信息: Permission denial
解决方案:检查module.json5中是否正确配置网络权限
json5
"requestPermissions": [
{
"name": "ohos.permission.INTERNET",
"reason": "$string:internet_permission_reason",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "inuse"
}
}
]
问题2:HTTPS证书校验失败
解决方案:在开发阶段可临时忽略证书校验(生产环境不推荐)
typescript
httpRequest.request(url, {
// 使用http协议仅用于开发测试
// 生产环境必须使用https并正确配置证书
})
7.2 UI渲染相关
问题3:列表数据更新后UI不刷新
解决方案:确保使用@State装饰状态变量,更新时触发刷新
typescript
// 错误做法
this.taskList[index].completed = true;
// 正确做法
this.taskList.splice(index, 1, { ...task, completed: true });
问题4:ForEach渲染警告:需要唯一的key标识
解决方案:确保ForEach的第三个参数返回唯一标识
typescript
ForEach(this.taskList, (task: TaskItem) => {
ListItem() { ... }
}, (task: TaskItem) => task.id.toString()) // 使用唯一ID作为key
7.3 资源引用相关
问题5:资源引用报错"Resource is not defined"
解决方案:使用$r()语法引用资源
typescript
// 错误写法
Text('加载中')
// 正确写法
Text($r('app.string.loading_text'))
7.4 Git操作相关
问题6:推送时提示"remote rejected"
解决方案:
bash
# 拉取远程最新代码
git pull origin main --rebase
# 解决冲突后推送
git push origin main
问题7:提交时报错"nothing to commit"
解决方案:检查文件状态
bash
# 查看文件状态
git status
# 添加文件
git add .
# 提交
git commit -m "feat: 添加任务列表功能"
八、测试与验证
8.1 模拟器运行
- 打开Device Manager
- 创建Phone模拟器(API 10+)
- 选择模拟器,点击运行按钮
8.2 功能验证清单
- 应用启动正常,显示任务列表页面
- 首次加载显示加载状态
- 网络请求成功,显示任务列表
- 点击任务项显示详情提示
- 长按任务项切换完成状态
- 下拉刷新功能正常
- 错误状态显示正确,重试功能可用
- 空数据状态显示正确
- 统计信息正确显示
8.3 日志记录
typescript
// 添加日志标签
const TAG = '[TaskListPage]';
// 使用console记录日志
console.log(`${TAG} 加载数据`);
console.error(`${TAG} 加载失败: ${error.message}`);
console.warn(`${TAG} 数据为空`);
九、代码提交规范
9.1 提交信息格式
遵循 Conventional Commits 规范:
<type>(<scope>): <subject>
<body>
<footer>
9.2 常用提交类型
| 类型 | 说明 | 示例 |
|---|---|---|
| feat | 新功能 | feat(task): 添加任务列表功能 |
| fix | 问题修复 | fix(network): 修复网络请求超时问题 |
| docs | 文档更新 | docs(readme): 更新项目说明文档 |
| style | 代码格式 | style(ui): 统一代码缩进格式 |
| refactor | 重构 | refactor(service): 重构网络请求层 |
| test | 测试 | test(api): 添加单元测试用例 |
| chore | 构建/工具 | chore(deps): 更新依赖版本 |
9.3 提交示例
bash
# 功能开发提交
git add .
git commit -m "feat(task): 实现任务列表数据加载与展示
- 添加网络请求封装类HttpUtil
- 添加任务数据服务TaskService
- 实现任务列表页面UI
- 支持下拉刷新和状态切换"
# 问题修复提交
git add .
git commit -m "fix(ui): 修复列表项点击事件无响应问题"
# 文档更新提交
git add README.md
git commit -m "docs(readme): 更新项目运行环境说明"
十、进阶优化方向
10.1 数据持久化
typescript
// 使用Preferences存储本地数据
import dataPreferences from '@ohos.data.preferences';
export class LocalStorage {
private static preferences: dataPreferences.Preferences | null = null;
static async init(context: Context): Promise<void> {
this.preferences = await dataPreferences.getPreferences(context, 'task_store');
}
static async saveTasks(tasks: TaskItem[]): Promise<void> {
await this.preferences?.put('tasks', JSON.stringify(tasks));
await this.preferences?.flush();
}
static async getTasks(): Promise<TaskItem[]> {
const data = await this.preferences?.get('tasks', '[]');
return JSON.parse(data as string);
}
}
10.2 状态管理
typescript
// 使用简单的状态管理
export class Store<T> {
private state: T;
private listeners: Array<(state: T) => void> = [];
constructor(initialState: T) {
this.state = initialState;
}
getState(): T {
return this.state;
}
setState(newState: Partial<T>): void {
this.state = { ...this.state, ...newState };
this.notify();
}
subscribe(listener: (state: T) => void): () => void {
this.listeners.push(listener);
return () => {
const index = this.listeners.indexOf(listener);
this.listeners.splice(index, 1);
};
}
private notify(): void {
this.listeners.forEach(listener => listener(this.state));
}
}
10.3 图片缓存
typescript
// 简单的图片缓存管理
export class ImageCache {
private static cache: Map<string, PixelMap> = new Map();
static async get(url: string): Promise<PixelMap | null> {
if (this.cache.has(url)) {
return this.cache.get(url)!;
}
const imageSource = image.createImageSource(url);
const pixelMap = await imageSource.createPixelMap();
this.cache.set(url, pixelMap);
return pixelMap;
}
static clear(): void {
this.cache.clear();
}
}
十一、总结
本文通过一个完整的网络请求与数据列表示例,介绍了HarmonyOS应用开发的核心流程:
11.1 核心知识点回顾
- 工程结构:合理的目录结构提升代码可维护性
- 配置文件:module.json5、oh-package.json5等核心配置
- 网络请求:基于@ohos.net.http的封装与使用
- UI组件:List、ForEach等组件实现列表展示
- 状态管理:@State装饰器的响应式更新机制
- 资源管理:字符串、颜色等资源的统一管理
11.2 关键收获
- 掌握鸿蒙应用的基本开发流程
- 了解网络请求的标准封装方式
- 熟悉列表组件的最佳实践
- 学会常见问题的排查与解决
11.3 下一步学习建议
- 深入学习ArkTS语法和特性
- 掌握更多UI组件的使用方法
- 学习应用数据持久化方案
- 了解分布式开发相关特性
- 探索性能优化技巧
参考资源: