1

在此处输入图像描述

有两种方法可以退出我们的 Android (Flutter) 应用程序,我们可以反复按返回按钮,也可以只按主页按钮

如果用户按下home button (不是后退按钮),则应用程序将在后台。我向用户发送 FCM(Firebase 云消息传递)推送通知,应用程序将在后台处理程序中接收消息。然后我像这样在共享首选项中保存一个字符串

Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  
  final prefs = await SharedPreferences.getInstance();
  await prefs.setString("myKey", "value here");
  
  final testValue = prefs.getString("myKey");
  print("value in background handler: $testValue");  // I confirm I can get the saved value here
}

正如您从上面的代码中看到的那样,我可以从共享首选项中获取值firebaseMessagingBackgroundHandler

用户收到推送通知后,打开应用,直接打开首页。

在主页中,我尝试获取我之前保存的值

  @override
  void initState() {
    super.initState();

    WidgetsBinding.instance?.addPostFrameCallback((_) async {

      final prefs = await SharedPreferences.getInstance();
      final savedValue = prefs.getString("myKey");
      print(savedValue); // I get null here initially

    });
  }

如您所见,当我直接返回应用程序时,我得到了 null 值。我必须再次使用退出应用程序back button,然后最终我可以从共享首选项中获取字符串值。

为什么我必须按返回按钮才能从共享偏好中获取值?如何解决这个问题?

4

1 回答 1

0

initState在第一次构建小部件之前执行一次。如果您将应用程序置于后台,然后再次打开它,initState将不会再次运行。

(不是您的问题的一部分,但即使您想在第一次构建之前从 Shared Preferences 中读取某些内容,initState也不是一个真正适合它的地方,因为它不能是异步的,这就是您使用的原因addPostFrameCallback。我宁愿建议例如,FutureBuilder在您的构建方法中使用 a ,以便您可以等待异步操作的结果,如果您需要它的结果进行构建。)

因此,您的值可能已保存到 Shared Preferences,但您需要找到另一种读取方式。如果您想检测您的应用程序何时从后台恢复,您可以通过观察应用程序生命周期变化来实现,请参阅本文中的示例。

但我认为有一种更简单的方法,如果您想在您的应用程序处于后台期间用户单击通知时获取通知数据。您可以收听onMessageOpenedApp,然后您可以直接在代码中获取消息,而无需共享首选项:

FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
  
});
于 2021-10-10T20:23:50.587 回答