연결된 소스 저장소의 README 원문 스냅샷입니다. 최신 내용은 저장소에서 확인하세요.
flutter_cache_store
A flexible cache manager for Flutter.
This package is highly inspired by flutter_cache_manager. Can be easily switched to each other.
Quick Start
import 'package:flutter_cache_store/flutter_cache_store.dart';
void demo(String url) async {
final store = await CacheStore.getInstance();
final file = await store.getFile(url);
}
APIs
CacheStore
void api() async {
CacheStore store = await CacheStore.getInstance(
namespace: 'unique_name',
policy: LeastFrequentlyUsedPolicy(),
clearNow: true,
fetch: myFetch,
);
store.fetch = myFetch;
File file = await store.getFile(
'url',
key: null,
headers: {},
fetch: myFetch,
custom: {'method': 'POST', 'body': 'test'},
flushCache: false,
);
await store.flush([
'key',
]);
await store.clearAll();
}
Future<Response> myFetch(url,
{Map<String, String> headers, Map<String, dynamic> custom}) {
final data = custom ?? {};
switch (data['method'] ?? '') {
case 'POST':
{
return post(url, headers: headers, body: data['body']);
}
default:
return get(url, headers: headers);
}
}
Cache File Structure
By default, the cached files will be saved under $TEMP/cache_store. $TEMP is generated by path_provider. The default temp filenames are timestamp-based 11 chars.
You can customize your own file structure under $TEMP/cache_store by overriding Policy. There is an example:
Let's suppose your are developing a reader for novels, and your app will cache chapters of books. Your API returns some IDs of books and chapters, and an ID only contains letters and digits.
class LRUCachePolicy extends LessRecentlyUsedPolicy {
LRUCachePolicy({int maxCount}) : super(maxCount: maxCount);
@override
String generateFilename({final String key, final String url}) =>
key;
}
void customizedCacheFileStructure() async {
CacheStore store = await CacheStore.getInstance(
policy: LRUCachePolicy(maxCount: 4096),
namespace: 'my_store',
);
String bookId = 'book123';
String chapterId = 'ch42';
String chapterUrl = 'https://example.com/book123/ch42';
File file = await store.getFile(
chapterUrl,
key: '$bookId/$chapterId',
);
}
Cache Policy
-
LessRecentlyUsedPolicy
LRU policy. Less Recently Used files will be removed when reached maxCount. Each time you access a file will update its used timestamp.
new LessRecentlyUsedPolicy(
maxCount: 999,
);
-
LeastFrequentlyUsedPolicy
LFU policy. Least Frequently Used files will be removed when reached maxCount. Each time you access a file will increase its hit count. After hitAge time the hit will expire. It will fallback to LRU policy if files have same hit count.
new LeastFrequentlyUsedPolicy(
maxCount: 999,
hitAge: Duration(days: 30),
);
-
CacheControlPolicy
Cache-Control header policy. This policy generally follows max-age=<seconds> or s-maxage=<seconds> rules of http response header Cache-Control. If the max-age-seconds not been set, it will use minAge unless you set it to null. The age will not be longer than maxAge.
new CacheControlPolicy(
maxCount: 999,
minAge: Duration(seconds: 30),
maxAge: Duration(days: 30),
);
-
FifoPolicy
First-In, First-Out policy, super simple and maybe for example only.
new FifoPolicy(
maxCount: 999,
);
Performance Warning
-
The implementation maintains all key-item in memory to improve the speed. So maxCount must between 1 and 100000 (100k) due to the cost of RAM and file system.
-
Currently, all the policies simply sort all items to expire files. It may hit performance due to O(N*logN) complexity.
Will switch to priority queue which has O(N*logK) while K usually is a very small number.
How to implement your own policy
The interface is a simple abstract class. You only have to implement a few methods.
abstract class CacheStorePolicy {
Future<Iterable<CacheItem>> cleanup(Iterable<CacheItem> allItems);
Future<void> clearAll(Iterable<CacheItem> allItems) async {}
Future<Iterable<CacheItem>> restore(List<CacheItem> allItems) async => allItems;
Future<void> onAdded(final CacheItem addedItem) async {}
Future<void> onAccessed(final CacheItem accessedItem, bool flushed) async {}
Future<void> onDownloaded(final CacheItem item, final Map<String, String> headers) async {}
Future<void> onFlushed(final Iterable<CacheItem> flushedItems) async {}
String generateFilename({final String key, final String url}) =>
Utils.genName();
}
-
Tips
You don't have to implement all of the onAdded, onAccessed and onDownloaded.