Flutter:共享首选项的奇怪行为
Posted
技术标签:
【中文标题】Flutter:共享首选项的奇怪行为【英文标题】:Flutter : Strange behavior of Shared Preferences 【发布时间】:2021-03-05 17:59:30 【问题描述】:我遇到了共享首选项值不一致的问题。我会尽量简单地描述它。
我正在使用 Firebase 云消息传递推送通知。当应用程序处于后台并收到通知时,将调用下面的后台处理程序。
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async
final SharedPreferences prefs = await SharedPreferences.getInstance();
final int counter = (prefs.getInt('badge') ?? 0) + 1;
prefs.setInt('badge', counter).then((bool success)
print(counter);
);
我的小部件使用 WidgetsBindingObserver 来确定生命周期状态。当我进入应用程序时,该小部件的状态为 onResume,我想从这样的共享首选项中读取该徽章值。
void didChangeAppLifecycleState(AppLifecycleState state)
if (state == AppLifecycleState.resumed)
final SharedPreferences prefs = await SharedPreferences.getInstance();
final int counter = (prefs.getInt('badge') ?? 0);
print(counter);
场景 1:
应用打开,收到通知 - 将徽章字段设置为 1。 应用在后台,收到通知 - 后台处理程序将徽章字段设置为 2。 应用程序已恢复,读取徽章字段,它仍然是 1。场景 2:
应用打开,收到通知 - 将徽章字段设置为 1。 应用在后台,收到通知 - 后台处理程序将徽章字段设置为 2。 应用在后台,收到通知 - 后台处理程序将徽章字段设置为 3。 应用程序已恢复,读取徽章字段,它仍然是 1。问题:知道为什么字段没有更新吗?
【问题讨论】:
你找到这个问题的答案了吗? 【参考方案1】:SharedPreferences 或任何其他本地存储在 _firebaseMessagingBackgroundHandler 中不起作用。
您应该在 getInitialMessage 或 onMessageOpenedApp 上捕获它。 https://firebase.flutter.dev/docs/messaging/notifications/
TL;DR: 当应用程序从终止状态打开时触发 getInitialMessage。当应用程序从后台状态打开时会触发 onMessageOpenedApp。
FirebaseMessaging.instance.getInitialMessage().then((RemoteMessage message)
if (message != null)
Navigator.of(context).pushNamed('/messages', arguments: message.data);
);
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message)
if (message != null)
Navigator.of(context).pushNamed('/messages', arguments: message.data);
);
【讨论】:
【参考方案2】:SharedPreferences 可用于后台事件处理程序。问题是后台处理程序在不同的隔离中运行,因此,当您尝试获取数据时,共享首选项实例为空。为避免这种情况,您只需强制刷新:
SharedPreferences prefs= await SharedPreferences.getInstance();
await prefs.reload();
final int counter = (prefs.getInt('badge') ?? 0);
在相同的模式下,如果可以在后台 hadler 中修改共享首选项,请确保在尝试读取它们的主隔离时调用此“重新加载”函数。
【讨论】:
reload 方法会清除共享首选项中的数据 能否请您进一步说明这一点 谢谢你!对于任何想知道的人,这里是 .reload() 的文档: 从主机平台获取最新值。使用此方法可以在应用程序运行时观察在本机代码中所做的修改(不使用插件)。以上是关于Flutter:共享首选项的奇怪行为的主要内容,如果未能解决你的问题,请参考以下文章
如何将对象列表中的布尔收藏夹保存到 Flutter 中的共享首选项