实现思路
- 选择缓存库:在Flutter中,可以使用
cached_network_image
库来实现图片缓存。它已经内置了根据URL缓存图片的功能。
- 设置缓存过期策略:可以通过自定义缓存管理类来实现过期策略。例如,记录图片缓存的时间戳,每次获取图片时检查时间戳与当前时间的差值,判断是否过期。
- 优先从缓存获取并后台更新:当图片过期时,先从缓存中获取旧图片显示,然后在后台发起新的网络请求更新缓存。
关键代码片段
- 引入依赖:
在
pubspec.yaml
文件中添加cached_network_image
依赖:
dependencies:
cached_network_image: ^3.2.3
- 自定义缓存管理类(示例):
import 'package:flutter/material.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:path_provider/path_provider.dart';
import 'dart:io';
import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
class CustomCacheManager extends BaseCacheManager {
static const key = 'customCacheKey';
final _prefs = SharedPreferences.getInstance();
static CustomCacheManager _instance;
factory CustomCacheManager() => _instance??= CustomCacheManager._();
CustomCacheManager._() : super(key);
@override
Future<File> getFile(String url) async {
final file = await super.getFile(url);
if (file.existsSync()) {
final prefs = await _prefs;
final timestamp = prefs.getDouble('$url - timestamp');
final now = DateTime.now().millisecondsSinceEpoch / 1000;
if (timestamp != null && now - timestamp > 3600) { // 假设缓存1小时过期
// 后台更新缓存
_updateCacheInBackground(url);
}
return file;
}
return super.getFile(url);
}
Future<void> _updateCacheInBackground(String url) async {
final file = await super.getFile(url);
if (file.existsSync()) {
final prefs = await _prefs;
await prefs.setDouble('$url - timestamp', DateTime.now().millisecondsSinceEpoch / 1000);
}
}
}
- 使用自定义缓存管理器显示图片:
class MyHomePage extends StatelessWidget {
final String imageUrl = 'https://example.com/image.jpg';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Cached Image'),
),
body: Center(
child: CachedNetworkImage(
imageUrl: imageUrl,
cacheManager: CustomCacheManager(),
placeholder: (context, url) => CircularProgressIndicator(),
errorWidget: (context, url, error) => Icon(Icons.error),
),
),
);
}
}