name: AsyncRedux 状态持久化
description: 使用 Persistor 实现本地状态持久化。涵盖创建自定义 Persistor 类、实现 readState()、persistDifference()、deleteState()、使用 LocalPersist 助手、节流保存、以及通过应用生命周期暂停/恢复持久化。
概述
AsyncRedux 通过向 Store 传递一个 persistor 对象来提供状态持久化。这将在磁盘上维护应用状态,实现在会话间恢复状态。
使用 Persistor 初始化 Store
在启动时,从磁盘读取任何现有状态,如果不存在则创建默认状态,然后初始化 store:
var persistor = MyPersistor();
var initialState = await persistor.readState();
if (initialState == null) {
initialState = AppState.initialState();
await persistor.saveInitialState(initialState);
}
var store = Store<AppState>(
initialState: initialState,
persistor: persistor,
);
Persistor 抽象类
Persistor<St> 基类定义了以下方法:
abstract class Persistor<St> {
/// 读取持久化状态,如果不存在则返回 null
Future<St?> readState();
/// 从磁盘删除状态
Future<void> deleteState();
/// 保存状态变化。提供 newState 和 lastPersistedState
/// 以便您可以比较它们并只保存差异。
Future<void> persistDifference({
required St? lastPersistedState,
required St newState
});
/// 初始保存的便捷方法
Future<void> saveInitialState(St state) =>
persistDifference(lastPersistedState: null, newState: state);
/// 控制保存频率。返回 null 以禁用节流。
Duration get throttle => const Duration(seconds: 2);
}
创建自定义 Persistor
扩展抽象类并实现所需方法:
class MyPersistor extends Persistor<AppState> {
@override
Future<AppState?> readState() async {
// 从磁盘读取状态(例如,从 SharedPreferences、文件等)
return null;
}
@override
Future<void> deleteState() async {
// 从磁盘删除状态
}
@override
Future<void> persistDifference({
required AppState? lastPersistedState,
required AppState newState,
}) async {
// 将状态保存到磁盘。
// 您可以比较 lastPersistedState 与 newState 以只保存变化。
}
@override
Duration get throttle => const Duration(seconds: 2);
}
节流
throttle getter 控制状态保存的频率。节流窗口内的所有变化被收集并在单个调用中保存。默认是 2 秒。
// 最多每 5 秒保存一次
@override
Duration get throttle => const Duration(seconds: 5);
// 禁用节流(每次变化立即保存)
@override
Duration? get throttle => null;
强制立即保存
派发 PersistAction() 以立即保存,绕过节流:
store.dispatch(PersistAction());
暂停和恢复持久化
使用以下 store 方法控制持久化:
store.pausePersistor(); // 暂停保存
store.persistAndPausePersistor(); // 保存当前状态,然后暂停
store.resumePersistor(); // 恢复保存
应用生命周期集成
当应用进入后台时暂停持久化,当应用变为活动时恢复。创建一个 AppLifecycleManager 小部件:
class AppLifecycleManager extends StatefulWidget {
final Widget child;
const AppLifecycleManager({
Key? key,
required this.child,
}) : super(key: key);
@override
_AppLifecycleManagerState createState() => _AppLifecycleManagerState();
}
class _AppLifecycleManagerState extends State<AppLifecycleManager>
with WidgetsBindingObserver {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
void didChangeAppLifecycleState(AppLifecycleState lifecycle) {
store.dispatch(ProcessLifecycleChange_Action(lifecycle));
}
@override
Widget build(BuildContext context) => widget.child;
}
创建一个动作来处理生命周期变化:
class ProcessLifecycleChange_Action extends ReduxAction<AppState> {
final AppLifecycleState lifecycle;
ProcessLifecycleChange_Action(this.lifecycle);
@override
Future<AppState?> reduce() async {
if (lifecycle == AppLifecycleState.resumed ||
lifecycle == AppLifecycleState.inactive) {
store.resumePersistor();
} else if (lifecycle == AppLifecycleState.paused ||
lifecycle == AppLifecycleState.detached) {
store.persistAndPausePersistor();
} else {
throw AssertionError(lifecycle);
}
return null;
}
}
用生命周期管理器包裹您的应用:
StoreProvider<AppState>(
store: store,
child: AppLifecycleManager(
child: MaterialApp( ... ),
),
)
LocalPersist 助手
LocalPersist 类简化了 Android/iOS 的磁盘操作。它适用于仅包含基本类型、列表和映射的简单对象结构。
import 'package:async_redux/local_persist.dart';
// 用文件名创建实例
var persist = LocalPersist("myFile");
// 保存数据
List<Object> simpleObjs = [
'Hello',
42,
true,
[100, 200, {"name": "John"}],
];
await persist.save(simpleObjs);
// 加载数据
List<Object> loaded = await persist.load();
// 追加数据
List<Object> moreObjs = ['more', 'data'];
await persist.save(moreObjs, append: true);
// 文件操作
int length = await persist.length();
bool exists = await persist.exists();
await persist.delete();
// 单个对象的 JSON 操作
await persist.saveJson(simpleObj);
Object? simpleObj = await persist.loadJson();
注意: LocalPersist 仅支持简单对象。对于复杂嵌套结构或自定义类,您需要自己实现序列化(例如,使用 toJson/fromJson 方法进行 JSON 编码)。
参考
文档中的 URL:
- https://asyncredux.com/sitemap.xml
- https://asyncredux.com/flutter/miscellaneous/persistence
- https://asyncredux.com/flutter/basics/store
- https://asyncredux.com/flutter/miscellaneous/database-and-cloud
- https://asyncredux.com/flutter/intro
- https://asyncredux.com/flutter/testing/mocking
- https://asyncredux.com/flutter/advanced-actions/redux-action
- https://asyncredux.com/flutter/about
- https://asyncredux.com/flutter/testing/store-tester
- https://asyncredux.com/flutter/miscellaneous/advanced-waiting