Flutter内存缓存管理插件lru_memory_cache的使用
Flutter内存缓存管理插件lru_memory_cache的使用
LRU缓存
LRUCache是一个Dart库,提供了用于内存数据存储的最近最少使用(LRU)缓存机制。它通过有效地管理频繁访问项的存储,解决了不必要的网络请求和陈旧数据持久化的问题。
问题
- 不必要的网络请求:从网络获取数据可能会消耗大量资源,并导致性能问题,特别是当相同的数据被频繁请求时。
- 陈旧数据持久化:缓存机制需要处理陈旧数据的移除,以确保缓存保持相关性和最新状态。
解决方案
LRUCache通过在内存中缓存数据来减少冗余的网络请求。它提供了为每个项目设置过期时间的功能,允许自动移除陈旧数据。
使用方法
LRUCache使用一个链式哈希映射来存储数据,并使用栈来跟踪最近使用的项目。
你可以向缓存中添加和获取项目。当你添加一个项目时,可以设置项目的过期时间。一旦日期过期,该项目将从缓存中移除。该项目会成为最近使用的项目。
当你访问一个项目时,该项目会变成最近使用的项目,其他项目会被推到栈的底部。
import 'package:lru_memory_cache/lru_memory_cache.dart';
LRUMemoryCache<String, int> cache = LRUMemoryCache(
generateKey: (k) => k.toString(),
capacity: 5,
expireMode: ExpireMode.autoExpire,
autoExpireCheckDuration: Duration(seconds: 1),
onExpire: (key, item) {
print("$item is expiring");
return true;
},
shouldRemoveOnCapacity: (key, item) {
print("Deciding to remove $item");
return item % 2 == 0;
},
onCapacityRemoved: (key, item) {
print("$item was removed due to capacity");
},
);
// 向缓存中添加项目
cache.add('key1', value: 42);
cache.add('key2', value: 87, expiryDuration: Duration(hours: 1));
// 从缓存中获取项目
int? result = cache.get('key1');
// 从缓存中获取多个项目
ManyResult<String, int> manyResult = cache.getMany(['key1', 'key2']);
// 完成后释放缓存
cache.dispose();
特性
动态容量
你可以根据应用程序的需求动态设置缓存的容量。
项目过期
设置项目在内存中保留的时间。此功能特别适用于处理频繁变化的数据。
项目持久性
可以选择使项目在缓存中持久存在,即使它已过期或是最少使用的项目。
过期模式
选择两种方式之一来移除过期项目:
- 自动过期:根据指定的持续时间自动移除项目。
- 交互时过期:仅在与缓存交互时(例如添加或检索项目时)移除项目。
全局过期时间
设置所有项目默认的过期时间,当未定义特定过期时间时使用。
API
LRUMemoryCache
LRUMemoryCache<K, V>({
required K Function(V data) generateKey,
int capacity = 100,
Duration? autoExpireCheckDuration,
Duration? globalExpiryTime,
bool Function(K, V)? onExpire,
void Function(K, V)? onCapacityRemoved,
bool Function(K, V)? shouldRemoveOnCapacity,
ExpireMode expireMode = ExpireMode.onInteraction,
bool Function(K, K)? equals,
int Function(K)? hashCode,
bool Function(dynamic)? isValidKey,
})
generateKey
: 从值生成键的函数。capacity
: 缓存的最大容量(默认:100)。autoExpireCheckDuration
: 自动过期检查的持续时间(如果expireMode
为ExpireMode.autoExpire
则必需)。globalExpiryTime
: 当未定义特定过期时间时,默认的项目过期时间。onExpire
: 在项目过期前触发的回调函数。onCapacityRemoved
: 当项目因达到容量而移除时触发的回调函数。shouldRemoveOnCapacity
: 在达到容量时决定是否移除项目的回调函数。expireMode
: 移除过期项目的选项(ExpireMode.autoExpire
或ExpireMode.onInteraction
)。equals
: 用于键比较的自定义相等函数。hashCode
: 用于键散列的自定义哈希函数。isValidKey
: 用于检查键是否有效的自定义函数。
属性
isAtCapacity
: 如果缓存达到其容量,则返回true。isNotAtCapacity
: 如果缓存还有空间添加更多项目,则返回true。capacity
: 获取或设置当前缓存的容量。
方法
add
: 添加具有可选过期持续时间的值到缓存。addMany
: 添加多个具有可选过期持续时间的值到缓存。get
: 通过键检索缓存中的值。getMany
: 通过键检索多个缓存中的值。dispose
: 清除缓存并停止自动过期计时器。
ExpireMode 枚举
定义了如何移除过期项目的选项:
autoExpire
: 根据指定的持续时间自动过期项目。onInteraction
: 仅在与缓存交互时(例如添加或检索项目时)过期项目。
ManyResult 类
由getMany
方法返回的结果类,包含找到和未找到的项目。
确保generateKeyFunction提供唯一的键,否则它们将被覆盖
import 'dart:async';
import 'package:lru_memory_cache/lru_memory_cache.dart';
Future<void> main() async {
LRUMemoryCache<String, int> cache = LRUMemoryCache(
generateKey: (k) => k.toString(),
capacity: 5,
expireMode: ExpireMode.onInteraction,
autoExpireCheckDuration: Duration(seconds: 1),
onExpire: (key, item) {
print("$item is expiring");
return true;
},
shouldRemoveOnCapacity: (key, item) {
print("Deciding to remove $item");
return item % 2 == 0;
},
onCapacityRemoved: (key, item) {
print("$item was removed due to capacity");
},
);
var list = List.generate(10, (index) => index + 1);
for (var r in list) {
cache.add(
r,
// expiryDuration: Duration(seconds: 5),
);
}
print(cache.data);
// Deciding to remove 1
// Deciding to remove 2
// 2 was removed due to capacity
// Deciding to remove 1
// Deciding to remove 3
// Deciding to remove 4
// 4 was removed due to capacity
// Deciding to remove 1
// Deciding to remove 3
// Deciding to remove 5
// Deciding to remove 6
// 6 was removed due to capacity
// Deciding to remove 1
// Deciding to remove 3
// Deciding to remove 5
// Deciding to remove 7
// Deciding to remove 8
// 8 was removed due to capacity
// Deciding to remove 1
// Deciding to remove 3
// Deciding to remove 5
// Deciding to remove 7
// Deciding to remove 9
// 1 was removed due to capacity
// [10, 9, 7, 5, 3]
}
更多关于Flutter内存缓存管理插件lru_memory_cache的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
1 回复