ArkTS网络缓存:HTTP请求缓存策略与实现
在移动应用开发中,网络请求的性能直接影响用户体验。频繁的网络请求不仅消耗流量,还可能导致页面加载缓慢、响应延迟等问题。ArkTS(Ark TypeScript)作为HarmonyOS应用开发的主力语言,提供了多种机制来优化网络请求,其中缓存策略是提升性能的关键手段之一。本文将详细介绍如何在ArkTS中实现HTTP请求的缓存管理,结合Preferences(首选项)存储实现本地缓存,并通过实际代码示例展示完整的缓存策略。
缓存策略概述
HTTP缓存是一种存储HTTP响应数据的机制,用于减少重复请求、降低服务器负载并提升应用响应速度。常见的缓存策略包括:
- 内存缓存:将数据临时存储在内存中,适用于短期频繁访问的数据,但应用重启后数据会丢失。
- 磁盘缓存:将数据持久化到本地存储(如文件系统或数据库),适用于长期缓存或离线访问。
- 混合缓存:结合内存缓存和磁盘缓存的优势,优先从内存读取,内存未命中时再读取磁盘。
在HarmonyOS开发中,Preferences(首选项)是一种轻量级的键值对存储工具,适合存储小体积的缓存数据(如API响应结果)。本文将以Preferences为基础,实现HTTP请求的磁盘缓存策略。
ArkTS HTTP请求基础
在实现缓存之前,首先需要了解ArkTS中HTTP请求的基本用法。HarmonyOS提供了@kit.NetworkKit模块,其中的http组件可用于发送网络请求。以下是一个简单的GET请求示例,来自项目中的ArkTSHttp示例:
// 导入http模块
import { http } from '@kit.NetworkKit';
import { BusinessError } from '@kit.BasicServicesKit';
private httpReq() {
// 创建httpRequest对象
let httpRequest = http.createHttp();
let url = "https://waylau.com/data/people.json";
let promise = httpRequest.request(
url,
{
method: http.RequestMethod.GET,
connectTimeout: 60000,
readTimeout: 60000,
header: {
'Content-Type': 'application/json'
}
}
);
// 处理响应结果
promise.then((data) => {
if (data.responseCode === http.ResponseCode.OK) {
console.info('Result:' + data.result);
this.message = JSON.stringify(data.result);
// TODO: 缓存响应结果
}
}).catch((err: BusinessError) => {
console.info('error:' + JSON.stringify(err));
});
}
上述代码通过http.createHttp()创建请求对象,发送GET请求并处理响应。接下来,我们将在此基础上添加缓存逻辑。
基于Preferences的缓存实现
Preferences是HarmonyOS提供的轻量级存储工具,适合存储键值对数据。项目中的ArkTSPreferences示例展示了如何使用Preferences进行数据持久化。以下是缓存实现的核心步骤:
1. 封装Preferences工具类
首先,封装一个PreferencesUtil工具类,提供缓存的增、删、查操作。代码来自PreferencesUtil.ets:
// 导入preferences模块
import { preferences } from '@kit.ArkData';
import { BusinessError } from '@kit.BasicServicesKit';
import { common } from '@kit.AbilityKit';
let context = getContext(this) as common.UIAbilityContext;
let options: preferences.Options = { name: 'http_cache' }; // 缓存文件名
export default class PreferencesUtil {
private dataPreferences: preferences.Preferences | null = null;
// 初始化Preferences实例
async getPreferencesFromStorage() {
await preferences.getPreferences(context, options).then((data) => {
this.dataPreferences = data;
console.info(`Succeeded in getting preferences`);
}).catch((err: BusinessError) => {
console.error(`Failed to get preferences, Cause:` + err);
});
}
// 存储缓存数据
async putCache(key: string, data: string, expiryTime?: number) {
if (!this.dataPreferences) await this.getPreferencesFromStorage();
// 缓存数据结构:{ data: string, expiry: number }
const cacheData = {
data: data,
expiry: expiryTime ? Date.now() + expiryTime * 1000 : Infinity
};
await this.dataPreferences.put(key, JSON.stringify(cacheData));
await this.dataPreferences.flush(); // 持久化到磁盘
}
// 获取缓存数据
async getCache(key: string): Promise<string | null> {
if (!this.dataPreferences) await this.getPreferencesFromStorage();
const cacheStr = await this.dataPreferences.get(key, '');
if (!cacheStr) return null;
const cacheData = JSON.parse(cacheStr);
// 检查缓存是否过期
if (cacheData.expiry < Date.now()) {
await this.removeCache(key); // 删除过期缓存
return null;
}
return cacheData.data;
}
// 删除缓存数据
async removeCache(key: string) {
if (!this.dataPreferences) await this.getPreferencesFromStorage();
await this.dataPreferences.delete(key);
await this.dataPreferences.flush();
}
}
2. 整合HTTP请求与缓存逻辑
接下来,修改HTTP请求代码,添加缓存读写逻辑。核心思路是:
- 请求前:先检查缓存,若缓存存在且未过期,则直接使用缓存数据。
- 请求后:若请求成功,将响应结果存入缓存。
修改后的代码如下:
// 导入PreferencesUtil
import PreferencesUtil from '../common/PreferencesUtil';
private preferencesUtil = new PreferencesUtil();
private CACHE_KEY = 'people_json_cache'; // 缓存键名
private CACHE_EXPIRY = 3600; // 缓存有效期(秒)
private async httpReqWithCache() {
// 1. 尝试读取缓存
const cachedData = await this.preferencesUtil.getCache(this.CACHE_KEY);
if (cachedData) {
console.info('Using cached data');
this.message = cachedData;
return; // 缓存命中,直接返回
}
// 2. 缓存未命中,发送网络请求
let httpRequest = http.createHttp();
let url = "https://waylau.com/data/people.json";
try {
let data = await httpRequest.request(url, {
method: http.RequestMethod.GET,
header: { 'Content-Type': 'application/json' }
});
if (data.responseCode === http.ResponseCode.OK) {
const result = JSON.stringify(data.result);
this.message = result;
// 3. 缓存响应结果(有效期1小时)
await this.preferencesUtil.putCache(this.CACHE_KEY, result, this.CACHE_EXPIRY);
}
} catch (err) {
console.error('HTTP request failed:', err);
}
}
3. 缓存控制与失效策略
为了保证缓存数据的有效性,需要合理设置缓存有效期(CACHE_EXPIRY)。对于频繁变化的数据(如实时新闻),可设置较短的有效期(如5分钟);对于静态数据(如城市列表),可设置较长的有效期(如24小时)。
此外,还可通过以下方式优化缓存策略:
- 强制刷新:提供手动刷新按钮,允许用户主动清除缓存并重新请求。
- 条件请求:结合HTTP头(如
If-Modified-Since、Etag),向服务器验证缓存是否过期。 - 缓存清理:定期清理过期缓存,避免存储空间不足。
完整示例与项目结构
本文涉及的代码来自项目中的以下路径:
- HTTP请求基础:samples/ArkTSHttp/entry/src/main/ets/pages/Index.ets
- Preferences工具类:samples/ArkTSPreferences/entry/src/main/ets/common/PreferencesUtil.ets
- 缓存页面示例:samples/ArkTSPreferences/entry/src/main/ets/pages/Index.ets
项目中还提供了其他网络相关示例,如ArkTSRdb(关系型数据库)和ArkTSDistributedData(分布式数据),可根据实际需求选择合适的存储方案。
总结与最佳实践
本文介绍了ArkTS中HTTP请求缓存的实现方法,基于Preferences实现了简单高效的磁盘缓存策略。总结以下最佳实践:
- 合理选择缓存方案:小体积数据(如API响应)优先使用
Preferences,大体积数据(如图片)可使用文件系统或数据库。 - 设置缓存有效期:根据数据更新频率设置合理的有效期,避免使用过期数据。
- 缓存清理机制:定期清理过期缓存,释放存储空间。
- 错误处理:网络请求失败时,可降级使用缓存数据,提升应用健壮性。
通过合理的缓存策略,可以显著提升应用的响应速度和离线体验。如需进一步优化,可结合HarmonyOS的分布式数据管理能力,实现多设备间的缓存同步。
本文示例代码基于项目中的ArkTSHttp和ArkTSPreferences模块,完整代码可在项目仓库中查看。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考




