Flutter中的网络请求图片存储为缓存,与定制删除本地缓存
Flutter中的网络请求图片存储为缓存,与定制删除本地缓存1:封装请求图片函数
2:访问的图片都会转为本地缓存,当相同的请求url,会在本地调用图片
3:本地缓存管理【windows与andriod已经测试】【有页面】【有调用案例】
4:删除本地缓存
清理缓存页面(下方代码中已包括)
https://i-blog.csdnimg.cn/direct/09748138705444a38574f734693567c2.png
https://i-blog.csdnimg.cn/direct/10231ff31f2f475abf873ac83ebc7fc2.png
windows中显示图片-----------安卓中显示图片
这里还没有进行优化图片显示的宽高,圆角,请自行设置
https://i-blog.csdnimg.cn/direct/c17733a638ff48cf81662740b6a5e91b.png
打印日志(显示图片请求的获取过程与报错原因)
https://i-blog.csdnimg.cn/direct/e824fdf76a2a44079c4517866211c20c.png
TuPianJiaZai 图片加载工具使用教程
注意事项
[*]imageUrl 可以为 null,此时会显示空白
[*]图片会自动缓存到本地
[*]支持自动重试3次
[*]默认有加载动画和错误提示
[*]支持所有尺度图片格式
现实应用场景
[*]商品展示卡片
[*]用户头像
[*]图片列表
[*]背景图片
[*]Banner图片
1. 基本用法
1.1导入文件
import '../utils/get_images/tupianjiazai.dart';
TuPianJiaZai.jiazaiTupian(
imageUrl: product.image,
width: double.infinity,
height: 200,
fit: BoxFit.cover,
)
2. 完整参数说明
TuPianJiaZai.jiazaiTupian(
// 必需参数
imageUrl: String?, // 图片URL,可以为null
// 可选参数
width: double?, // 显示宽度
height: double?, // 显示高度
fit: BoxFit, // 图片填充方式,默认BoxFit.cover
cacheWidth: int?, // 缓存图片宽度,用于优化内存
cacheHeight: int?, // 缓存图片高度,用于优化内存
placeholder: Widget?, // 加载时显示的占位Widget
errorWidget: Widget?, // 加载失败时显示的Widget
)
3. 使用案例
3.1 基础加载
TuPianJiaZai.jiazaiTupian(
imageUrl: 'https://example.com/image.jpg',
width: 200,
height: 200,
)
3.2 自定义占位图和错误图
TuPianJiaZai.jiazaiTupian(
imageUrl: imageUrl,
width: 300,
height: 200,
placeholder: const Center(
child: CircularProgressIndicator(),
),
errorWidget: const Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: ,
),
),
)
3.3 列表项中使用
ListView.builder(
itemBuilder: (context, index) {
return TuPianJiaZai.jiazaiTupian(
imageUrl: imageUrls,
height: 150,
fit: BoxFit.cover,
cacheWidth: 600, // 优化缓存大小
cacheHeight: 400,
);
},
)
请自行在\lib\utils\get_images\文件夹中创建一下设置
D:\F\luichun\lib\utils\get_images\huancunguanli.dart
import 'dart:io';
import 'dart:typed_data';
import 'package:path_provider/path_provider.dart';
import 'package:crypto/crypto.dart';
import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:synchronized/synchronized.dart';
import 'logger.dart';// 使用统一的日志管理器
import '../env_config.dart';// 本地进行开发时,使用 会对 localhost:10005 进行请求,但是安卓模拟器需要把localhost转换为 10.0.2.2
/// 完整工作流程:
/// 1.应用启动 -> 初始化缓存目录
/// 2.请求图片 -> 检查缓存 -> 返回缓存或null
/// 3.下载图片 -> 保存图片 -> 更新映射关系
/// 4.定期维护 -> 清理缓存/计算大小
/// 图片缓存管理器
/// 用于管理图片的本地缓存,减少重复的网络请求
class HuanCunGuanLi {
/// 单例模式
/// 使用工厂构造函数确保全局只有一个缓存管理器实例
/// 避免重复创建缓存目录和资源浪费
static final HuanCunGuanLi _instance = HuanCunGuanLi._internal();
/// 缓存目录
Directory? _cacheDir;
/// 初始化锁
final _lock = Lock();
/// 初始化标志
bool _isInitialized = false;
/// 持久化存储的键名
static const String _prefKey = 'image_cache_urls';
// 工厂构造函数
factory HuanCunGuanLi() {
return _instance;
}
// 私有构造函数
HuanCunGuanLi._internal();
/// 确保已初始化
Future<void> _ensureInitialized() async {
if (_isInitialized) return;// 快速检查
await _lock.synchronized(() async {
if (_isInitialized) return;// 双重检查
await init();
});
}
/// 初始化缓存目录
Future<void> init() async {
try {
final appDir = await getApplicationDocumentsDirectory();
final cacheDir = Directory('${appDir.path}/image_cache');
if (!await cacheDir.exists()) {
await cacheDir.create(recursive: true);
}
_cacheDir = cacheDir;
_isInitialized = true;
if (EnvConfig.isDevelopment) {
ImageLogger.logCacheInfo('缓存系统初始化完成: ${_cacheDir!.path}');
}
} catch (e) {
ImageLogger.logCacheError('缓存系统初始化失败', error: e);
rethrow;
}
}
/// 3异步获取缓存图片
/// 参数:
/// url: 图片的网络地址
/// 返回:
/// Uint8List?: 图片的二进制数据,不存在时返回null
/// 流程:
/// 1. 根据URL生成缓存键
/// 2. 查找本地缓存文件
/// 3. 返回缓存数据或null
Future<Uint8List?> huoquTupian(String url) async {
await _ensureInitialized();
try {
final cacheKey = _shengchengKey(url);
final cacheFile = File('${_cacheDir!.path}/$cacheKey');
if (await cacheFile.exists()) {
ImageLogger.logCacheDebug('从缓存加载图片', {'url': url});
return await cacheFile.readAsBytes();
}
return null;
} catch (e) {
ImageLogger.logCacheError('读取缓存图片失败', error: e);
return null;
}
}
/// 异步保存图片到缓存
/// 图片URL
/// 图片二进制数据
Future<void> baocunTupian(String url, Uint8List imageBytes) async {
await _ensureInitialized();
final cacheKey = _shengchengKey(url);
final cacheFile = File('${_cacheDir!.path}/$cacheKey');
await cacheFile.writeAsBytes(imageBytes);
await _baocunURLyingshe(url, cacheKey);
}
/// 生成缓存键
/// 使用MD5加密URL生成唯一标识
String _shengchengKey(String url) {
final bytes = utf8.encode(url);
final digest = md5.convert(bytes);
return digest.toString();
}
/// 4. URL 映射管理:
/// 保存URL映射关系
/// 实现:
/// 1. 获取SharedPreferences实例
/// 2. 读取现有映射
/// 3. 更新映射关系
/// 4. 序列化并保存
/// 使用 SharedPreferences 持久化存储 URL 映射关系
/// JSON 序列化保存映射数据
/// 异步操作避免阻塞主线程
/// 保存URL映射关系
Future<void> _baocunURLyingshe(String url, String cacheKey) async {
final prefs = await SharedPreferences.getInstance();
final Map<String, String> urlMap = await _huoquURLyingshe();
urlMap = cacheKey;
await prefs.setString(_prefKey, jsonEncode(urlMap));
}
/// 获取URL映射关系
Future<Map<String, String>> _huoquURLyingshe() async {
final prefs = await SharedPreferences.getInstance();
final String? mapJson = prefs.getString(_prefKey);
if (mapJson != null) {
return Map<String, String>.from(jsonDecode(mapJson));
}
return {};
}
/// 5.缓存清理功能:
/// 清除所有缓存
/// 使用场景:
/// 1. 应用清理存储空间
/// 2. 图片资源更新
/// 3. 缓存出现问题时重置
/// 递归删除缓存目录
/// 清除 URL 映射数据
/// 清除所有缓存
Future<void> qingchuHuancun() async {
await _cacheDir!.delete(recursive: true);
await _cacheDir!.create();
final prefs = await SharedPreferences.getInstance();
await prefs.remove(_prefKey);
}
///6 .缓存大小计算:
///- 异步遍历缓存目录
/// 累计所有文件大小
/// 使用 Stream 处理大目录
/// 获取缓存大小(字节)
Future<int> huoquHuancunDaxiao() async {
int size = 0;
await for (final file in _cacheDir!.list()) {
if (file is File) {
size += await file.length();
}
}
return size;
}
}
D:\F\luichun\lib\utils\get_images\logger.dart
import 'package:logger/logger.dart';
/// 图片加载系统的日志管理器
class ImageLogger {
static final Logger _logger = Logger(
printer: PrettyPrinter(
methodCount: 0,
errorMethodCount: 8,
lineLength: 120,
colors: true,
printEmojis: true,
dateTimeFormat: DateTimeFormat.onlyTimeAndSinceStart,
),
);
// 缓存系统日志
static void logCacheInfo(String message) {
_logger.i('
页:
[1]