> 技术文档 > Cangjie/HarmonyOS-Examples 缓存机制实现:本地缓存与网络缓存

Cangjie/HarmonyOS-Examples 缓存机制实现:本地缓存与网络缓存


Cangjie/HarmonyOS-Examples 缓存机制实现:本地缓存与网络缓存

【免费下载链接】HarmonyOS-Examples 本仓将收集和展示仓颉鸿蒙应用示例代码,欢迎大家投稿,在仓颉鸿蒙社区展现你的妙趣设计! 【免费下载链接】HarmonyOS-Examples 项目地址: https://gitcode.com/Cangjie/HarmonyOS-Examples

引言:为什么需要缓存机制?

在移动应用开发中,缓存(Cache)机制是提升应用性能、优化用户体验的关键技术。当用户在网络不稳定或离线状态下使用应用时,合理的缓存策略能够确保应用的流畅运行和数据的一致性。Cangjie/HarmonyOS-Examples 项目作为仓颉鸿蒙应用示例集合,展示了多种缓存实现方案。

本文将深入探讨 HarmonyOS 应用中的缓存机制实现,涵盖本地缓存和网络缓存两大核心领域,帮助开发者构建高性能的鸿蒙应用。

缓存机制架构设计

整体架构图

mermaid

缓存层次结构

缓存层级 存储介质 适用场景 生命周期 内存缓存 RAM 高频访问数据 应用运行时 本地存储 设备存储 用户配置、离线数据 长期保存 网络缓存 服务器+本地 网络资源、API响应 可配置时效

本地缓存实现方案

1. Preferences 数据存储

Preferences 是 HarmonyOS 提供的轻量级数据存储方案,适用于存储简单的键值对数据。

// 引入 Preferences 模块import preferences from \'@ohos.data.preferences\';// 创建 Preferences 实例const context = getContext(this);const preferences = await preferences.getPreferences(context, \'userSettings\');// 存储数据await preferences.put(\'username\', \'JohnDoe\');await preferences.put(\'theme\', \'dark\');await preferences.flush();// 读取数据const username = await preferences.get(\'username\', \'defaultUser\');const theme = await preferences.get(\'theme\', \'light\');// 删除数据await preferences.delete(\'username\');

2. 文件系统缓存

对于较大的数据或文件,可以使用文件系统进行缓存存储。

// 文件缓存管理器实现class FileCacheManager { private cacheDir: string; constructor() { this.cacheDir = globalThis.context.filesDir + \'/cache/\'; // 确保缓存目录存在 this.ensureCacheDirectory(); } private async ensureCacheDirectory(): Promise { try { await fs.mkdir(this.cacheDir); } catch (error) { // 目录已存在 } } // 存储文件到缓存 async saveToCache(key: string, data: ArrayBuffer): Promise { const filePath = this.cacheDir + this.hashKey(key); await fs.write(filePath, data); } // 从缓存读取文件 async readFromCache(key: string): Promise { const filePath = this.cacheDir + this.hashKey(key); try { return await fs.read(filePath); } catch (error) { return null; } } // 清理过期缓存 async cleanupExpiredCache(maxAge: number): Promise { const files = await fs.listFile(this.cacheDir); const now = Date.now(); for (const file of files) { const stat = await fs.stat(this.cacheDir + file); if (now - stat.mtime > maxAge) { await fs.unlink(this.cacheDir + file); } } } private hashKey(key: string): string { // 简单的哈希函数实现 return key.split(\'\').reduce((a, b) => { a = ((a << 5) - a) + b.charCodeAt(0); return a & a; }, 0).toString(16); }}

3. 数据库缓存策略

对于结构化数据,可以使用关系型数据库进行缓存管理。

// 数据库缓存实现import relationalStore from \'@ohos.data.relationalStore\';class DatabaseCache { private rdbStore: relationalStore.RdbStore; async initDatabase(): Promise { const config: relationalStore.StoreConfig = { name: \'app_cache.db\', securityLevel: relationalStore.SecurityLevel.S1 }; const sql = `CREATE TABLE IF NOT EXISTS cache_data ( key TEXT PRIMARY KEY, value TEXT, timestamp INTEGER, expiry INTEGER )`; this.rdbStore = await relationalStore.getRdbStore(globalThis.context, config); await this.rdbStore.executeSql(sql); } async set(key: string, value: string, ttl: number = 3600): Promise { const timestamp = Date.now(); const expiry = timestamp + ttl * 1000; const valueBucket: relationalStore.ValuesBucket = { \'key\': key, \'value\': value, \'timestamp\': timestamp, \'expiry\': expiry }; await this.rdbStore.insert(\'cache_data\', valueBucket); } async get(key: string): Promise { const predicates = new relationalStore.RdbPredicates(\'cache_data\'); predicates.equalTo(\'key\', key); const result = await this.rdbStore.query(predicates, [\'value\', \'expiry\']); if (result.rowCount > 0) { const row = await result.goToFirstRow(); const expiry = result.getLong(row, result.getColumnIndex(\'expiry\')); if (Date.now() < expiry) { return result.getString(row, result.getColumnIndex(\'value\')); } else { // 数据已过期,删除 await this.delete(key); } } return null; }}

网络缓存实现方案

1. HTTP 缓存控制

// HTTP 缓存拦截器class HttpCacheInterceptor { private cache: Map = new Map(); async intercept(request: Request): Promise { const cacheKey = this.generateCacheKey(request); // 检查缓存 const cachedResponse = this.getFromCache(cacheKey); if (cachedResponse && !this.isCacheExpired(cachedResponse)) { return cachedResponse.data; } // 发起网络请求 const response = await fetch(request); // 缓存响应 if (this.shouldCache(response)) { this.saveToCache(cacheKey, response, this.getCacheTTL(response)); } return response; } private generateCacheKey(request: Request): string { return `${request.method}:${request.url}:${JSON.stringify(request.headers)}`; } private shouldCache(response: Response): boolean { return response.status === 200 && response.headers.get(\'Cache-Control\') !== \'no-cache\'; } private getCacheTTL(response: Response): number { const cacheControl = response.headers.get(\'Cache-Control\'); if (cacheControl) { const maxAgeMatch = cacheControl.match(/max-age=(\\d+)/); if (maxAgeMatch) { return parseInt(maxAgeMatch[1], 10); } } return 300; // 默认5分钟 }}

2. 图片资源缓存

// 图片缓存组件@Componentstruct CachedImage { @State private imageData: PixelMap | null = null; @State private isLoading: boolean = true; private cacheManager: ImageCacheManager = new ImageCacheManager(); aboutToAppear() { this.loadImage(this.src); } async loadImage(url: string) { // 首先尝试从缓存加载 const cachedImage = await this.cacheManager.getImage(url); if (cachedImage) { this.imageData = cachedImage; this.isLoading = false; return; } // 缓存未命中,从网络加载 try { const response = await fetch(url); const arrayBuffer = await response.arrayBuffer(); const imageSource = image.createImageSource(arrayBuffer); const pixelMap = await imageSource.createPixelMap(); // 缓存图片 await this.cacheManager.cacheImage(url, pixelMap); this.imageData = pixelMap; this.isLoading = false; } catch (error) { console.error(\'Failed to load image:\', error); } } build() { Column() { if (this.isLoading) { LoadingIndicator() } else if (this.imageData) { Image(this.imageData) } } }}

缓存策略与最佳实践

缓存更新策略对比

策略类型 实现方式 优点 缺点 适用场景 先读缓存 先检查缓存,命中则返回,否则请求网络 响应速度快 数据可能不是最新的 对实时性要求不高的数据 先读网络 先请求网络,成功则更新缓存并返回 数据最新 网络延迟影响体验 对实时性要求高的数据 并行策略 同时读取缓存和网络,先返回缓存再更新 兼顾速度和新鲜度 实现复杂 大多数场景 懒更新 缓存过期后仍使用,后台更新 用户体验流畅 数据可能陈旧 可容忍数据延迟的场景

缓存清理机制

// 智能缓存清理策略class SmartCacheCleaner { private static readonly CLEANUP_INTERVAL = 24 * 60 * 60 * 1000; // 24小时 start() { setInterval(() => this.cleanup(), SmartCacheCleaner.CLEANUP_INTERVAL); } async cleanup() { await this.cleanExpiredPreferences(); await this.cleanOldFiles(); await this.optimizeDatabase(); } private async cleanExpiredPreferences(): Promise { const prefs = await preferences.getPreferences(globalThis.context, \'cache_metadata\'); const keys = await prefs.getAllKeys(); for (const key of keys) { const expiry = await prefs.get(key + \'_expiry\', 0); if (Date.now() > expiry) { await prefs.delete(key); await prefs.delete(key + \'_expiry\'); } } } private async cleanOldFiles(): Promise { const cacheDir = globalThis.context.filesDir + \'/cache/\'; const sevenDaysAgo = Date.now() - 7 * 24 * 60 * 60 * 1000; const files = await fs.listFile(cacheDir); for (const file of files) { const stat = await fs.stat(cacheDir + file); if (stat.mtime < sevenDaysAgo) { await fs.unlink(cacheDir + file); } } }}

性能优化与监控

缓存命中率监控

// 缓存性能监控class CachePerformanceMonitor { private hits: number = 0; private misses: number = 0; private totalSize: number = 0; recordHit() { this.hits++; } recordMiss() { this.misses++; } getHitRate(): number { const total = this.hits + this.misses; return total > 0 ? this.hits / total : 0; } // 导出监控数据 exportMetrics(): CacheMetrics { return { hitRate: this.getHitRate(), totalRequests: this.hits + this.misses, cacheSize: this.totalSize, timestamp: Date.now() }; }}interface CacheMetrics { hitRate: number; totalRequests: number; cacheSize: number; timestamp: number;}

总结

Cangjie/HarmonyOS-Examples 项目展示了鸿蒙应用开发中完整的缓存机制实现方案。通过合理的本地缓存和网络缓存策略,开发者可以:

  1. 提升应用性能:减少网络请求,加快数据加载速度
  2. 优化用户体验:支持离线使用,提供流畅的操作体验
  3. 降低服务器压力:合理利用缓存减少不必要的网络请求
  4. 节省用户流量:避免重复下载相同资源

在实际开发中,应根据具体业务需求选择合适的缓存策略,并建立完善的缓存监控和清理机制,确保缓存数据的有效性和一致性。

通过本文介绍的缓存实现方案,开发者可以构建出高性能、用户体验优秀的鸿蒙应用,为用户提供更加流畅和可靠的服务。

【免费下载链接】HarmonyOS-Examples 本仓将收集和展示仓颉鸿蒙应用示例代码,欢迎大家投稿,在仓颉鸿蒙社区展现你的妙趣设计! 【免费下载链接】HarmonyOS-Examples 项目地址: https://gitcode.com/Cangjie/HarmonyOS-Examples

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考