Flutter中如何在Alarm Isolate与主Isolate间共享持久化存储?
Isolate间数据同步问题解决办法
方案1:用shared_preferences的reload搞定
每个Isolate里的shared_preferences会维护独立的内存缓存,Alarm Isolate写完数据后,主Isolate得主动调用reload()从磁盘拉取最新数据,不然读的还是旧缓存内容。
Alarm Isolate代码
import 'package:shared_preferences/shared_preferences.dart'; // 写入数据 final prefs = await SharedPreferences.getInstance(); await prefs.setString("data", data);
主Isolate代码
import 'package:shared_preferences/shared_preferences.dart'; // 读取前先同步磁盘数据 final prefs = await SharedPreferences.getInstance(); await prefs.reload(); // 关键操作:重新加载磁盘中的最新数据 final updatedData = prefs.getString("data");
如果需要实时感知数据变化,可以结合Isolate消息通信:Alarm Isolate写入完成后,发消息通知主Isolate调用reload()同步数据。
方案2:Isolate直接传消息(最快,无需磁盘IO)
跳过磁盘读写,直接用Isolate的消息机制传递数据,既保证同步效率,又不会出现缓存不一致问题。
第一步:主Isolate创建接收端口,将发送端口传给Alarm Isolate
import 'dart:isolate'; import 'package:android_alarm_manager_plus/android_alarm_manager_plus.dart'; void main() async { // 创建接收端口,用于接收Alarm Isolate的消息 final receivePort = ReceivePort(); // 将发送端口作为参数传给Alarm Isolate await AndroidAlarmManager.oneShot( const Duration(seconds: 5), 0, alarmCallback, params: receivePort.sendPort, ); // 监听Alarm Isolate发来的数据更新 receivePort.listen((message) { if (message is Map && message.containsKey('data')) { // 更新主Isolate本地数据 final updatedData = message['data']; // 这里处理数据逻辑 } }); }
第二步:Alarm Isolate通过发送端口传递数据给主Isolate
void alarmCallback(SendPort? sendPort) async { // 生成或修改目标数据 final data = "更新后的内容"; // 将最新数据发送给主Isolate sendPort?.send({'data': data}); // 可选:将数据持久化到shared_preferences作为备份 final prefs = await SharedPreferences.getInstance(); await prefs.setString("data", data); }
如果主Isolate修改了数据,也可以用同样的逻辑:让Alarm Isolate创建接收端口并将发送端口传给主Isolate,主Isolate修改完成后发消息通知同步。
方案3:优化get_storage的使用(备选)
get_storage的问题在于每个Isolate有独立的内存缓存,所以读取前需要强制从磁盘重新加载,比如每次读取前重新初始化:
// 每次读取前重新初始化,会重新加载磁盘数据 await GetStorage.init(); final updatedData = GetStorage().read("data");
不过这种方式每次读取都要初始化,效率不如前两种方案,仅作为备选方案使用。
内容的提问来源于stack exchange,提问作者Ahsan Sarwar
相关产品推荐
相关产品推荐

