Flutter数据缓存插件cached的使用
Flutter数据缓存插件cached的使用
简介
cached
是一个用于简化Dart类中缓存机制创建的简单包。它支持多种缓存策略,如LRU(Least Recently Used)算法,并且可以与持久化存储结合使用。本文将详细介绍如何在Flutter项目中使用cached
插件进行数据缓存。
安装配置
添加依赖
首先,在pubspec.yaml
文件中添加以下依赖:
dependencies:
cached_annotation:
dev_dependencies:
cached:
build_runner:
或者直接运行命令来安装:
flutter pub add --dev cached
flutter pub add --dev build_runner
flutter pub add cached_annotation
运行生成器
为了使代码生成器生效,需要执行以下命令:
flutter pub run build_runner build
确保你的文件顶部包含必要的导入语句和部分声明:
import 'package:cached_annotation/cached_annotation.dart';
part 'some_file.cached.dart';
基本用法
使用@WithCache
注解
为类添加缓存功能,可以通过@WithCache()
注解实现。例如:
@WithCache(useStaticCache: true) // 可选参数:是否使用静态缓存
abstract mixin class RemoteRepository implements Repository, _$RemoteRepository {
factory RemoteRepository({required SomeApiDataSource dataSource}) = _RemoteRepository;
@Cached(
ttl: 60, // 缓存存活时间(秒)
syncWrite: true, // 同步写入模式
limit: 100 // 最大缓存条目数
)
Future<SomeResponseType> getSthData() async {
return await dataSource.getData();
}
}
清除特定方法的缓存
你可以通过@ClearCached
或@ClearAllCached
注解清除缓存。比如清除单个方法的缓存:
@ClearCached('getSthData')
void clearGetUserData();
或者清除所有缓存:
@clearAllCached
void clearAllData();
持久化存储
如果你希望将缓存保存到持久化存储中(如SharedPreferences),可以使用@PersistentCached
注解。这要求你实现一个继承自CachedStorage
接口的具体类,并将其实例分配给PersistentStorageHolder.storage
。
例如:
class MyStorageImpl extends CachedStorage {
final _storage = MyExternalStorage();
@override
Future<Map<String, dynamic>> read(String key) async {
return await _storage.read(key);
}
@override
Future<void> write(String key, Map<String, dynamic> data) async {
await _storage.write(key, data);
}
@override
Future<void> delete(String key) async {
await _storage.delete(key);
}
@override
Future<void> deleteAll() async {
await _storage.deleteAll();
}
}
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
PersistentStorageHolder.storage = await MyStorageImpl();
runApp(const MyApp());
}
示例代码
下面是一个完整的示例程序,展示了如何在Flutter应用中集成cached
插件并实现简单的API响应缓存。
import 'package:flutter/material.dart';
import 'package:cached_annotation/cached_annotation.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
part 'main.cached.dart';
// 模拟的数据源
class ApiDataSource {
static const String url = "https://jsonplaceholder.typicode.com/posts/1";
Future<Map<String, dynamic>> getData() async {
final response = await http.get(Uri.parse(url));
if (response.statusCode == 200) {
return json.decode(response.body);
} else {
throw Exception('Failed to load post');
}
}
}
// 使用WithCache标记的仓库类
@WithCache()
abstract mixin class PostRepository implements _$PostRepository {
factory PostRepository({required ApiDataSource dataSource}) = _PostRepository;
final ApiDataSource _dataSource;
@Cached(
ttl: 60,
syncWrite: true,
where: shouldCacheResponse,
)
Future<Map<String, dynamic>> getPostData() async {
return await _dataSource.getData();
}
bool shouldCacheResponse(Map<String, dynamic> response) {
// 根据条件决定是否缓存
return response['id'] != null && response['title'] != null;
}
@ClearCached('getPostData')
void clearPostDataCache() {}
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: PostScreen(),
);
}
}
class PostScreen extends StatefulWidget {
@override
_PostScreenState createState() => _PostScreenState();
}
class _PostScreenState extends State<PostScreen> {
final PostRepository repository = PostRepository(dataSource: ApiDataSource());
Map<String, dynamic>? postData;
@override
void initState() {
super.initState();
_fetchData();
}
Future<void> _fetchData() async {
try {
final data = await repository.getPostData();
setState(() {
postData = data;
});
} catch (e) {
print(e);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Cached Plugin Example')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
onPressed: () => _fetchData(),
child: Text('Fetch Data'),
),
SizedBox(height: 20),
postData != null
? Text('Title: ${postData!['title']}')
: Text('No data available.'),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
repository.clearPostDataCache();
setState(() {
postData = null;
});
},
child: Text('Clear Cache'),
),
],
),
),
);
}
}
此示例展示了如何利用cached
插件快速设置一个带有缓存功能的API请求处理逻辑。通过点击按钮触发数据获取操作,并且可以手动清除缓存以重新加载最新数据。
更多关于Flutter数据缓存插件cached的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter数据缓存插件cached的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用cached_network_image
插件进行数据缓存的示例代码。这个插件允许你从网络加载图片,并自动缓存它们,以便在后续的应用启动或页面刷新时能够快速加载。
首先,你需要在你的pubspec.yaml
文件中添加cached_network_image
依赖:
dependencies:
flutter:
sdk: flutter
cached_network_image: ^3.1.0 # 请检查最新版本号
然后,运行flutter pub get
来安装依赖。
接下来,你可以在你的Flutter应用中使用CachedNetworkImage
小部件来加载和缓存网络图片。以下是一个简单的示例:
import 'package:flutter/material.dart';
import 'package:cached_network_image/cached_network_image.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Cached Network Image Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Cached Network Image Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
// 使用CachedNetworkImage加载并缓存网络图片
CachedNetworkImage(
imageUrl: 'https://example.com/path/to/your/image.jpg',
placeholder: (context, url) => CircularProgressIndicator(),
errorWidget: (context, url, error) => Icon(Icons.error),
fit: BoxFit.cover,
width: 300,
height: 200,
),
SizedBox(height: 20),
// 另一个示例,展示不同配置
CachedNetworkImage(
imageUrl: 'https://example.com/another/image.png',
placeholder: (context, url) => Icon(Icons.image),
errorWidget: (context, url, error) => Text('Failed to load image'),
retryCount: 3, // 重试次数
retryDuration: Duration(seconds: 2), // 每次重试之间的间隔
fadeDuration: Duration(milliseconds: 300), // 图片加载完成时的淡入效果时长
),
],
),
),
);
}
}
在这个示例中,我们展示了如何使用CachedNetworkImage
小部件加载并缓存网络图片。你可以自定义placeholder
(占位符,在图片加载时显示),errorWidget
(当加载图片失败时显示的组件),以及其他一些配置选项,如retryCount
(重试次数),retryDuration
(每次重试之间的间隔),和fadeDuration
(图片加载完成时的淡入效果时长)。
这样,你的应用就可以有效地缓存网络图片,提高用户体验。