Flutter用AndroidAlarmManagerPlus更新SharedPreferences取不到最新值问题
问题根因
AndroidAlarmManager的回调运行在独立Dart Isolate中,与应用主Isolate内存完全隔离,二者的SharedPreferences内存缓存不互通。- 后台Isolate更新的是持久化存储中的数据,主Isolate的SharedPreferences缓存仍保留应用进入paused状态前的旧值,因此resumed时读取拿到旧数据,只有应用销毁重启清空缓存后才能读取到最新值。
解决方案
方案1:读取前强制同步持久化数据(最简便)
修改你的Utils.getInt工具方法,读取前调用SharedPreferences的reload()方法,强制同步磁盘上的最新数据,清空当前Isolate的内存缓存:
// 修改Utils类的getInt实现 static Future<int?> getInt(String key) async { final sp = await SharedPreferences.getInstance(); // 同步磁盘最新数据到当前Isolate await sp.reload(); return sp.getInt(key); }
该方案实现成本极低,适合SP读取频率不高的场景。
方案2:Isolate通信同步缓存(性能更优)
后台Isolate执行完updateTime的存储逻辑后,通过SendPort向主Isolate发送更新通知,主Isolate收到通知后更新自身缓存或本地变量,无需每次读取都刷磁盘,性能更好,适合高频读写的场景。
额外优化点
当前代码每次进入paused状态都会重复注册同ID的周期闹钟,建议注册前先取消已存在的同ID任务,避免重复触发:
update(int id, Function callback) async { // 先取消已有同ID闹钟,避免重复注册 await AndroidAlarmManager.cancel(id); print('alram: started ${DateTime.now()}'); final value = await AndroidAlarmManager.periodic( Duration(minutes: 1), id, callback, allowWhileIdle: true, exact: true, wakeup: true, ); print('is alarm on? $value'); }
内容的提问来源于stack exchange,提问作者Mohammad Safayet Latif
相关产品推荐
相关产品推荐

