【问题标题】:Running a task in a Flutter app at certain times在特定时间在 Flutter 应用程序中运行任务
【发布时间】:2021-06-07 22:10:18
【问题描述】:

你好颤振/移动开发者,

我手头有一个特殊的问题,我需要一些建议。我需要创建一个在一天中的特定时间执行特定任务的应用程序。时间每天都会变化,它会在午夜(或非高峰时间)通过 REST 调用获取更新的时间。无论如何,任务必须在预定的时间完成,即使在设备重启等之后。我已经对此进行了广泛的研究,我感觉 Flutter 不能很好地处理预定的任务,尤其是在 iOS 中,它可以终止一个无论出于何种原因应用。

我研究过的选项是:

  1. workmanager (https://pub.dev/packages/workmanager/changelog):这似乎是最有希望的,如果不是最低频率 15 分钟,这对我来说还不够。如果是时候完成任务,我需要每分钟检查一次。有没有办法绕过这个限制?

  2. 本机解决方案。我对原生 iOS 和 Android 编码几乎没有经验,所以我不喜欢这个解决方案。但是通过一些研究,我看到了一些可以通过这种方法安排任务的示例。

  3. 服务器端通知。从表面上看,这似乎是一个很好的解决方案,我需要这方面的建议。是否该运行任务的计算将发生在服务器端,并且可以向设备发送通知(例如通过 Firebase),这将触发任务运行。这是否可行,设备在收到通知时会实际运行代码吗?

所以这些是我的选择。你觉得哪个最可行?如果比我有更多移动经验的人可以帮助我,我将不胜感激,也许有比我提出的三个更好的解决方案。谢谢。

【问题讨论】:

  • " 有没有办法绕过这个限制?" ... 仅当 Apple 更改其政策时。
  • 我看到了this 视频,其中介绍了一些配置行为的策略/模式,我认为这些策略/模式不仅仅适用于视频名称(“Firebase 远程配置”)。

标签: android ios swift flutter scheduled-tasks


【解决方案1】:

时间每天都会变化,它会在午夜(或非高峰时段)通过 REST 调用获取更新的时间。

这闻起来像是糟糕的建筑。为什么?

  • 您在午夜对更新服务器进行 DDOS 攻击(如果您在同一时区有很多用户)。您可以将 HTTP 请求错开几秒钟来解决此问题,但这是一种临时解决方案,而不是长期解决方案。
  • 因为您正在反转依赖关系:听起来时间是服务器的责任(因此您的客户调用它来询问最新时间)。您的客户端不应该是请求服务器更新的人,因为现在您的客户端有 2 个作业:安排计划更新并为用户安排计划任务。让客户端询问服务器是错误的方向。您应该从服务器发送消息以更新设备上的日程安排。
  • 即使您轮询服务器以获取计划更新,您也应该在您想要的时间安排移动应用程序通知/警报。使用静默通知是 iOS 上后台调度限制的已知解决方法。在 Android 上,WorkManager 是not the right library,你应该使用AlarmManager
  • 下面是另一个 StackOverflow 考虑使用本地通知来解决问题的方法:They used flutter_local_notifications

回答要点

  1. 在 Android 上,不要使用 WorkManager,而是使用 AlarmManager,甚至更好的是安排通知。话虽如此,Android 上存在一些制造商特定的怪癖,请参阅 flutter_local_notifications 文档:

因此,当应用程序在某些设备(例如小米、华为)上处于后台时,计划通知可能无法工作。如果您遇到这样的问题,那么这就是原因。由于是操作系统的限制,插件无法解决。

  1. 不需要使用 Native 代码,通知是标准功能。
  2. 您可以暂时保留轮询架构,因为它更简单(但更脏)。即使您愿意使用服务器端架构,我也会从服务器向客户端发送消息以仅更新客户端计划,不触发工作/用户警报,否则您当听起来不需要互联网时,正在使您的应用程序依赖于互联网(与社交媒体通知不同)。对于连接不良的设备,这会导致糟糕的用户体验。

【讨论】:

  • 感谢您的详细回复。能把使用flutter_local_notifications的stackoverflow问题的链接加进去吗?
  • 哦,对不起,我以为我添加了它。 here
  • 嗨 Ben,我有一个关于 flutter_local_notifications 的问题。该插件看起来只会在预定时间显示通知。但是有没有办法在预定的时间运行其他任务?提前致谢。
  • 我以为您实际上可以使用通知来触发后台工作,但这是不可能的。如果您使用 FCM,您可以发送“数据消息”来触发后台工作,但这很复杂,并且使您的应用程序依赖于互联网,如前所述。所以最后,我发现了这个,我认为安排工作会很有用:pub.dev/packages/workmanager
  • 我想限制是你不能安排一个确切的时间,如前所述。所以我想在 Android 上你可以使用android_alarm_manager。我会看看如何在 iOS 上完成它
【解决方案2】:

您可以通过 Firebase 发送数据通知,并使用 onBackgroundMessage 回调处理它们。见这里:https://firebase.flutter.dev/docs/messaging/usage#background-messages

Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  // If you're going to use other Firebase services in the background, such as Firestore,
  // make sure you call `initializeApp` before using other Firebase services.
  await Firebase.initializeApp();

  print("Handling a background message: ${message.messageId}");
}

void main() {
  FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
  runApp(MyApp());
}

来自文档(Android/Apple):

  1. 不能是匿名函数。
  2. 它必须是顶级函数(例如,不是需要初始化的类方法)。

【讨论】:

    猜你喜欢
    • 2016-10-07
    • 2011-10-07
    • 1970-01-01
    • 1970-01-01
    • 2022-01-22
    • 1970-01-01
    • 2012-09-18
    • 2020-05-24
    • 1970-01-01
    相关资源
    最近更新 更多