HarmonyOS APP开发---“壁纸控“壁纸App,需要用到这个库
·
HarmonyOS APP开发—"壁纸控"壁纸App,需要用到这个库
想做一个壁纸 App,几百张高清大图瀑布流加载?不缓存等于每次重新下载,不做降采样 4K 图直接 OOM——
@ohos/imageknife的二级缓存 + 降采样 + 生命周期管理,让瀑布流丝滑到底。
📦 仓库地址:https://gitcode.com/CPF-ApplicationTPC/ImageKnife | 安装:
ohpm install @ohos/imageknife
写在前面
“壁纸控"的核心挑战是"图片多、图片大”:
- 瀑布流一次加载几十张 4K 壁纸,不缓存 = 每次重新下载 = 流量爆炸
- 4K 图直接解码进内存 = 单张 30MB+ = 几张就 OOM
- 用户快速滑动,已滑出的图片请求还在跑 = 浪费资源
@ohos/imageknife 基于 Glide 思路,提供了完整的解决方案:内存 LRU 缓存 + 磁盘二级缓存 + 内存降采样 + 生命周期感知。
⚠️ ImageKnife 已停止演进,新项目推荐 imageknifepro。本文仍适用于维护中的存量项目。
这篇文章聊什么
- 瀑布流加载——WaterFlow + ImageKnife 组件
- 缓存策略——内存缓存 + 磁盘缓存 + 降采样
- 预加载——下一条壁纸提前拉进缓存
第一步:安装
ohpm install @ohos/imageknife
需要图片变换(模糊、亮度等)时额外装:
ohpm install @ohos/gpu_transform
第二步:瀑布流加载壁纸
import { ImageKnife, ImageKnifeOption, ImageKnifeComponent } from '@ohos/imageknife'
@Entry
@Component
struct WallpaperPage {
@State wallpapers: string[] = [
'https://cdn.example.com/wallpaper/4k_001.jpg',
'https://cdn.example.com/wallpaper/4k_002.jpg',
'https://cdn.example.com/wallpaper/4k_003.jpg',
// ... 更多壁纸
]
aboutToAppear() {
// 配置内存缓存 100MB
ImageKnife.with().initMemoryCache(100 * 1024 * 1024)
}
build() {
WaterFlow() {
ForEach(this.wallpapers, (url: string) => {
FlowItem() {
ImageKnifeComponent({
imageKnifeOption: {
loaderSource: { uri: url },
placeholder: $r('app.media.placeholder'),
errorholder: $r('app.media.error'),
// 降采样:按目标尺寸采样,4K 图不会全量进内存
downsampleOf: 'smallest',
}
})
.width('100%')
.aspectRatio(0.6)
}
}, (url: string) => url)
}
.columnsTemplate('1fr 1fr')
.width('100%').height('100%')
}
}
降采样是"壁纸控"不 OOM 的关键——4K 图按显示尺寸(约 300px 宽)采样后,内存从 30MB 降到几百 KB。
第三步:下载进度 + 仅缓存加载
// 带下载进度
ImageKnifeComponent({
imageKnifeOption: {
loaderSource: { uri: url },
onProgressUpdate: (received, total) => {
console.info(`下载进度: ${Math.ceil(received / total * 100)}%`)
},
}
})
// 离线模式:仅从缓存加载,不走网络
ImageKnifeComponent({
imageKnifeOption: {
loaderSource: { uri: url },
onlyRetrieveFromCache: true, // 缓存没有就显示 errorholder
}
})
第四步:预加载下一条壁纸
用户还在看第 3 张时,提前把第 4、5 张拉进缓存:
// 预加载(不显示,只进缓存)
ImageKnife.with().preLoadCache('https://cdn.example.com/wallpaper/4k_004.jpg')
ImageKnife.with().preLoadCache('https://cdn.example.com/wallpaper/4k_005.jpg')
// 用户滑到第 4 张时,内存缓存已命中,秒开
为什么"壁纸控"选了 ImageKnife?
| 需求 | 原生 Image | @ohos/imageknife |
|---|---|---|
| 内存缓存 | ❌ | ✅ LRU |
| 磁盘缓存 | ❌ | ✅ 二级缓存 |
| 降采样 | ❌ | ✅ 防 OOM |
| 下载进度 | ❌ | ✅ 回调 |
| 预加载 | ❌ | ✅ preLoadCache |
| 生命周期感知 | ❌ | ✅ 销毁自动取消 |
| 离线模式 | ❌ | ✅ onlyRetrieveFromCache |
总结
"壁纸控"这个场景里,@ohos/imageknife 解决了三件事:
- 不 OOM——降采样让 4K 图按显示尺寸进内存,30MB → 几百 KB
- 不重下——内存 + 磁盘二级缓存,滑过的图再滑回来秒开
- 不浪费——预加载 + 生命周期感知,该提前拉的提前拉,该取消的自动取消
如果你也在做壁纸、相册、电商商品图等海量图片场景,@ohos/imageknife 的缓存体系能让你省心一大半。(新项目建议直接用 imageknifepro)
更多推荐

所有评论(0)