Flutter:共享偏好的奇怪行为



我遇到了共享首选项值不一致的问题。我会尽量简单地描述它。

我正在使用Firebase云消息进行推送通知。当应用程序处于后台并收到通知时,将调用后台处理程序below。

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

问题:知道为什么字段没有更新吗?

SharedPreferences可以用于后台事件处理程序。问题是后台处理程序在不同的隔离中运行,因此,当您尝试获取数据时,共享首选项实例是空的。为了避免这种情况,你只需强制刷新:

SharedPreferences prefs= await SharedPreferences.getInstance();
await prefs.reload();
final int counter = (prefs.getInt('badge') ?? 0);

在相同的模式下,如果共享的首选项可以在后台hadler中修改,请确保您将其称为";重新加载";当你试图从主隔离区中读取时,函数。

SharedPreferences或任何其他本地存储都无法在_firebaseMessagingBackgroundHandler中工作。

您应该在getInitialMessage或onMessageOpenedApp上捕获它。https://firebase.flutter.dev/docs/messaging/notifications/

TL;博士:当应用程序从终止状态打开时,会触发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);
}
});

最新更新