51

我一直在寻找这个,但没有找到任何包或在 Flutter 中安排后台任务的方法。就像在 Android 中一样,有WorkManager, AlarmManager

我知道我可以使用 访问这些类MethodChannel,但我想要一些适用于 iOS 和 Android 的东西。

(移动框架没有调度后台任务的能力非常令人失望)。

4

3 回答 3

24

有一篇Medium 博客文章解释了如何做到这一点。
但是我们认为设置起来太复杂了,所以碰巧我们创建了一个插件来帮助您。

//Provide a top level function or static function.
//This function will be called by Android and will return the value you provided when you registered the task.
//See below
void callbackDispatcher() {
  Workmanager.executeTask((task) {
    print("Native echoed: $task");
    return Future.value(true);
  });
}

Workmanager.initialize(
    callbackDispatcher, //the top level function.
    isInDebugMode: true //If enabled it will post a notification whenever the job is running. Handy for debugging jobs
)

我们支持 Android 的 Workmanager 和 iOS performFetch


目前它仅适用于 Android 项目,但我们很快就会关注 iOS。
我会在可用时更新此答案。


我们现在也支持 iOS。它仍然是早期的 alpha,但试一试。
我们也写了一篇免费的Medium帖子。

于 2019-07-31T06:37:20.063 回答
8

解决方案 1: android_alarm_manager_plus是调度后台任务的最佳解决方案。但唯一的缺点是只支持Android。

注意: 如果您使用的是android_alarm_manager版本,请迁移到 Plus 版本:D

开始吧:

像往常一样将此插件导入您的项目后,将以下内容添加到标签内的 AndroidManifest.xml 中:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>

接下来,在标签中,添加:

<service
    android:name="io.flutter.plugins.androidalarmmanager.AlarmService"
    android:permission="android.permission.BIND_JOB_SERVICE"
    android:exported="false"/>
<receiver
    android:name="io.flutter.plugins.androidalarmmanager.AlarmBroadcastReceiver"
    android:exported="false"/>
<receiver
    android:name="io.flutter.plugins.androidalarmmanager.RebootBroadcastReceiver"
    android:enabled="false">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"></action>
    </intent-filter>
</receiver>

然后在 Dart 代码中添加:

import 'package:android_alarm_manager/android_alarm_manager.dart';

void printHello() {
  final DateTime now = DateTime.now();
  final int isolateId = Isolate.current.hashCode;
  print("[$now] Hello, world! isolate=${isolateId} function='$printHello'");
}

main() async {
  final int helloAlarmID = 0;
  await AndroidAlarmManager.initialize();
  runApp(...);
  await AndroidAlarmManager.periodic(const Duration(minutes: 1), helloAlarmID, printHello);
}

如果您想每天在特定时间安排任何任务,您需要执行以下操作:

if (Platform.isAndroid) {
   await AndroidAlarmManager.periodic(
      const Duration(hours: 24), //Do the same every 24 hours
      helloAlarmID, //Different ID for each alarm
      printHello,
      wakeup: true, //the device will be woken up when the alarm fires
      startAt: DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day, 5, 0), //Start whit the specific time 5:00 am
      rescheduleOnReboot: true, //Work after reboot
   );
}

如果警报回调需要访问其他 Flutter 插件,包括警报管理器插件本身,则可能需要通知后台服务如何初始化插件,具体取决于应用程序正在使用哪个 Flutter Android 嵌入。

这是通过给 AlarmService 一个回调来调用应用程序的 onCreate 方法来完成的。

具体来说,它的Application类如下:

public class Application extends FlutterApplication implements PluginRegistrantCallback {
    @Override
    public void onCreate() {
        super.onCreate();
        AlarmService.setPluginRegistrant(this);
    }

    @Override
    public void registerWith(PluginRegistry registry) {
        //add AndroidAlarmManagerPlugin plugin register  if you work with arlarm
        AndroidAlarmManagerPlugin.registerWith(registry.registrarFor("io.flutter.plugins.androidalarmmanager.AndroidAlarmManagerPlugin"));
    }
}

这必须反映在应用程序的 AndroidManifest.xml 中。例如:

<application
        android:name=".Application"
        ...

解决方案 2: Cron是安排后台任务的另一个最佳解决方案。Cron 以固定的时间、日期或间隔定期运行任务。但是玉米的唯一缺点是一旦应用程序被杀死,cron 无法按预期在后台工作。

一个简单的使用示例:

import 'package:cron/cron.dart';

main() {
  var cron = new Cron();
  cron.schedule(new Schedule.parse('*/3 * * * *'), () async {
    print('every three minutes');
  });
  cron.schedule(new Schedule.parse('8-11 * * * *'), () async {
    print('between every 8 and 11 minutes');
  });
}

一般如何设置 cronjob:信息

测试 cronjob:crontab

于 2020-04-18T22:43:13.193 回答
3

使用WorkManager

dependencies:
  workmanager: ^0.2.3

WorkManager分为两个部分,它们在后台运行任务。

1、后台工作延迟

registerOneOffTask 只运行一次任务,初始延迟为 10 秒。当我们只需要执行一次任何后台工作时,这很有用。

例子:

Workmanager.registerOneOffTask(
  "1",
  "registerOneOffTask",
  initialDelay: Duration(seconds: 10),
);

2. 定期后台工作

此任务定期运行,由于我们没有提供频率,因此默认为 15 分钟。 例子:

Workmanager.registerPeriodicTask(
  "2",
  "registerPeriodicTask",
  initialDelay: Duration(seconds: 10),
);

有关详细说明,请关注博客:

https://medium.com/flutterworld/flutter-perform-b​​ackground-job-9bce92f0a21e

于 2021-03-08T14:26:55.263 回答