Appearance
缓存机制
鸿蒙缓存:内存缓存、KV-Store 缓存、图片缓存、LruCache。
1. 缓存层级
用户请求数据
│
▼
┌─ 内存缓存(最快,LruCache)─────┐
│ 命中 → 直接返回 │
│ 未命中 → │
│ ↓ │
├─ KV-Store 缓存(中速)───────────┐
│ 命中 → 返回 │
│ 未命中 → │
│ ↓ │
├─ 本地文件缓存(较慢)─────────────┐
│ 命中 → 返回 │
│ 未命中 → │
│ ↓ │
└─ 网络请求(最慢) │
│
返回数据 │
│ │
▼ ▼
存入各级缓存(回填)2. LruCache 内存缓存
2.1 实现 LRU 缓存
typescript
class LruCache<K, V> {
private maxSize: number
private cache: Map<K, V>
constructor(maxSize: number = 100) {
this.maxSize = maxSize
this.cache = new Map()
}
// 获取缓存
get(key: K): V | undefined {
let value = this.cache.get(key)
if (value !== undefined) {
// 更新访问顺序(移到最新)
this.cache.delete(key)
this.cache.set(key, value)
}
return value
}
// 设置缓存
put(key: K, value: V): void {
if (this.cache.size >= this.maxSize) {
// 删除最久未使用的(Map 第一个)
let firstKey = this.cache.keys().next().value
this.cache.delete(firstKey)
}
this.cache.set(key, value)
}
// 删除缓存
remove(key: K): void {
this.cache.delete(key)
}
// 清空缓存
clear(): void {
this.cache.clear()
}
// 获取大小
size(): number {
return this.cache.size
}
}2.2 图片缓存
typescript
class ImageCache {
private cache: LruCache<string, imagePixel.ImagePixel> = new LruCache(50)
// 从缓存获取
get(url: string): imagePixel.ImagePixel | null {
return this.cache.get(url) || null
}
// 设置缓存
put(url: string, pixel: imagePixel.ImagePixel): void {
this.cache.put(url, pixel)
}
// 加载图片(先查缓存,再下载)
async load(url: string): Promise<imagePixel.ImagePixel> {
let cached = this.get(url)
if (cached) {
console.log('缓存命中:', url)
return cached
}
// 缓存未命中,下载
let pixel = await this.downloadImage(url)
this.put(url, pixel)
return pixel
}
private async downloadImage(url: string): Promise<imagePixel.ImagePixel> {
let httpClient = http.createHttp()
let response = await httpClient.request(url, {
method: http.HttpRequestMethod.GET
})
httpClient.destroy()
// 图片解码...
return pixel
}
}3. 缓存策略
3.1 缓存过期策略
typescript
interface CacheEntry<V> {
data: V
timestamp: number
ttl: number // 生存时间(毫秒)
}
class TimeCache<V> {
private cache: Map<string, CacheEntry<V>> = new Map()
get(key: string): V | null {
let entry = this.cache.get(key)
if (!entry) return null
// 检查是否过期
if (Date.now() - entry.timestamp > entry.ttl) {
this.cache.delete(key)
return null
}
return entry.data
}
put(key: string, data: V, ttl: number = 3600000): void {
this.cache.set(key, {
data: data,
timestamp: Date.now(),
ttl: ttl
})
}
// 清理过期条目
cleanup(): void {
let now = Date.now()
for (let [key, entry] of this.cache.entries()) {
if (now - entry.timestamp > entry.ttl) {
this.cache.delete(key)
}
}
}
}3.2 缓存方案对比
| 方案 | 速度 | 容量 | 持久化 | 适用场景 |
|---|---|---|---|---|
| 内存缓存 | ⚡⚡⚡ | 小 | ❌ | 频繁访问数据 |
| KV-Store 缓存 | ⚡⚡ | 中 | ✅ | 应用重启后恢复 |
| 文件缓存 | ⚡ | 大 | ✅ | 图片/大文件 |
| AssetStore | ⚡ | 小 | ✅ 卸载保留 | 敏感数据 |
4. 面试高频考点
Q1: 鸿蒙推荐哪些缓存策略?
回答:内存(LruCache)→ KV-Store → 文件 → 网络。多级缓存,最近最常使用优先。
Q2: 图片缓存如何实现?
回答:先查 LruCache 内存缓存,命中直接返回;未命中下载图片,解码后存入缓存并返回。
🐱 小猫提示:缓存机制记住 "LruCache 内存、多级缓存、TTL 过期、图片先查缓存再下载"。