Flutter数据缓存插件cached_repository的使用
Flutter数据缓存插件cached_repository的使用
简单易用且可扩展的数据缓存库,可用于存储你需要的所有数据。 灵感来源于Android中的NetworkBoundResource。
如果你觉得有用,请给项目点赞以支持我们
资源
开始使用
只需创建一个包含CachedRepository
字段的类,并开始缓存数据:
class SomeClassRepository {
SomeClassRepository(SomeClassApi someClassApi)
: _cachedRepo = CachedRepository.persistent(
'my_objects',
fetch: (String key, [__]) => someClassApi.getObjects(key),
decode: (json) => SomeClass.listFromJson(json),
cacheDuration: const Duration(hours: 12),
);
final CachedRepository<String, List<SomeClass>> _cachedRepo;
final _logger = Logger();
Stream<Resource<List<SomeClass>>> getMyObjectsStream(
String parameter, {
bool forceReload = false,
}) {
_logger.d('SomeClassRepository => getMyObjectsStream');
return _cachedRepo.stream(parameter, forceReload: forceReload);
}
Future<Resource<List<SomeClass>>> getMyObjects(
String parameter, {
bool forceReload = false,
}) {
_logger.d('SomeClassRepository => getMyObjects');
return _cachedRepo.first(parameter, forceReload: forceReload);
}
Future<void> invalidate(String parameter) {
_logger.d('SomeClassRepository => invalidate');
return _cachedRepo.invalidate(parameter);
}
Future<void> removeObjectFromCache(
String parameter, {
/*required*/ String objectId,
}) async {
_logger.d('SomeClassRepository => removeObjectFromCache');
return _cachedRepo.updateValue(parameter, (list) {
return list.where((it) => it.id != objectId).toList(growable: false);
});
}
Future<void> removeObjectsFromCache(
String parameter, {
/*required*/ List<String> objectIds,
}) async {
_logger.d('SomeClassRepository => removeObjectsFromCache');
return _cachedRepo.updateValue(parameter, (list) {
return list
?.where((it) => !objectIds.contains(it.id))
?.toList(growable: false);
});
}
Future<void> clear(String parameter) {
_logger.d('SomeClassRepository => clear');
return _cachedRepo.clear(parameter);
}
}
class SomeClass {
final String id;
SomeClass(this.id);
factory SomeClass.fromJson(Map<String, dynamic> json) {
return SomeClass(
json['id'],
);
}
Map<String, dynamic> toJson() {
return {
'id': id,
};
}
static List<SomeClass> listFromJson(List<dynamic>/*?*/ jsonList) =>
(jsonList ?? [])
.map((json) => SomeClass.fromJson(json))
.toList(growable: false);
}
abstract class SomeClassApi {
factory SomeClassApi() => _SomeClassFakeApi();
Future<List<SomeClass>> getObjects(String parameter);
Future<void> create(String id);
}
class _SomeClassFakeApi implements SomeClassApi {
final _logger = Logger();
List<SomeClass> myObjects = [
SomeClass('1'),
SomeClass('2'),
SomeClass('3'),
];
[@override](/user/override)
Future<List<SomeClass>> getObjects(String parameter) async {
_logger.d('SomeClassFakeApi => getObjects');
await Future.delayed(const Duration(seconds: 1));
return myObjects;
}
[@override](/user/override)
Future<void> create(String id) async {
_logger.d('SomeClassFakeApi => create');
await Future.delayed(const Duration(seconds: 1));
myObjects = myObjects
..add(SomeClass(id))
..toList();
}
}
你可以使用自己的类替换SomeClass
和SomeClassApi
。
欢迎提交拉取请求。
完整示例代码
import 'package:example/some_class_repository.dart';
import 'package:example/some_class_service.dart';
import 'package:flutter/material.dart';
import 'package:logger/logger.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key key}) : super(key: key);
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key key}) : super(key: key);
[@override](/user/override)
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
static const _someParameter = 'key';
final _logger = Logger();
/*late final*/
SomeClassService _service;
[@override](/user/override)
void initState() {
final api = SomeClassApi();
final repository = SomeClassRepository(api);
_service = SomeClassService(
someClassApi: api,
someClassRepository: repository,
);
super.initState();
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('标题'),
),
body: Center(
child: StreamBuilder(
stream:
_service.getMyObjectsStream(_someParameter, forceReload: true),
builder: (context, res) {
if (res.data?.hasData ?? false) {
_logger.d(
'Value (stream): ${(res.data.data as List<SomeClass>).map((e) => e.toJson()).toList()}');
return Text(
'数据: ${res.data.data.map((e) => e.toJson()).toList()}');
} else if (res.data?.isError ?? false) {
_logger.d('错误 (stream): ${res.data.error}');
}
_logger.d('加载中 (stream)');
return const Text('正在加载...');
},
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => _service.create(_someParameter),
tooltip: '创建',
child: const Icon(Icons.add),
),
);
}
}
更多关于Flutter数据缓存插件cached_repository的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter数据缓存插件cached_repository的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,cached_repository
是一个在 Flutter 中用于数据缓存的非常有用的库。它结合了数据获取和缓存机制,使得管理数据变得更加高效。以下是一个如何使用 cached_repository
的示例代码案例。
首先,确保你已经在 pubspec.yaml
文件中添加了 cached_repository
依赖:
dependencies:
flutter:
sdk: flutter
cached_repository: ^x.y.z # 请替换为最新版本号
然后运行 flutter pub get
来获取依赖。
接下来,我们来看一个具体的示例,假设我们要缓存从网络获取的用户数据。
1. 创建一个数据源类
import 'package:dio/dio.dart';
import 'package:cached_repository/cached_repository.dart';
class UserDataSource implements DataSource<UserModel, String> {
final Dio dio;
UserDataSource({required this.dio});
@override
Future<UserModel> fetchData(String key) async {
// 模拟从网络获取用户数据
final response = await dio.get('https://api.example.com/users/$key');
return UserModel.fromJson(response.data);
}
}
2. 创建用户模型类
class UserModel {
final String id;
final String name;
final String email;
UserModel({required this.id, required this.name, required this.email});
factory UserModel.fromJson(Map<String, dynamic> json) {
return UserModel(
id: json['id'] as String,
name: json['name'] as String,
email: json['email'] as String,
);
}
Map<String, dynamic> toJson() {
return {
'id': id,
'name': name,
'email': email,
};
}
}
3. 创建缓存仓库类
import 'package:cached_repository/cached_repository.dart';
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
import 'user_data_source.dart';
import 'user_model.dart';
class UserRepository extends CachedRepository<UserModel, String> {
UserRepository({required UserDataSource dataSource})
: super(
dataSource: dataSource,
cacheManager: DefaultCacheManager(),
keyMapper: (UserModel data) => data.id, // 使用用户ID作为缓存键
);
}
4. 使用缓存仓库
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
import 'user_repository.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late UserRepository userRepository;
UserModel? user;
@override
void initState() {
super.initState();
final dio = Dio();
final userDataSource = UserDataSource(dio: dio);
userRepository = UserRepository(dataSource: userDataSource);
// 假设我们要获取ID为'1'的用户数据
_fetchUserData('1');
}
Future<void> _fetchUserData(String userId) async {
try {
// 尝试从缓存中获取数据,如果缓存中没有,则从数据源获取并缓存
user = await userRepository.fetch(userId);
setState(() {});
} catch (e) {
print('Error fetching user data: $e');
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('User Data'),
),
body: Center(
child: user == null
? CircularProgressIndicator()
: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('ID: ${user!.id}'),
Text('Name: ${user!.name}'),
Text('Email: ${user!.email}'),
],
),
),
),
);
}
}
在这个示例中,我们创建了一个 UserDataSource
来从网络获取用户数据,一个 UserModel
来表示用户数据,一个 UserRepository
来结合数据源和缓存管理,最后在 MyApp
中使用 UserRepository
来获取并显示用户数据。
这个示例展示了如何使用 cached_repository
进行数据缓存,从而减少不必要的网络请求,提高应用性能。