如何在Flutter中调度后台任务?

jgwigjjp  于 2023-03-24  发布在  Flutter
关注(0)|答案(3)|浏览(194)

我一直在寻找这个,但还没有找到任何包或一种方法来安排在Flutter的后台任务。像在Android中有WorkManagerAlarmManager
我知道我可以使用MethodChannel访问这些类,但我想要的东西适用于iOS和Android。
(Its非常令人失望的是,移动的框架没有调度后台任务的能力)。

igsr9ssn

igsr9ssn1#

有一个Medium blogpost解释了如何做到这一点。
然而,我们认为这是太复杂的方式设置,所以它只是碰巧我们创建了一个plugin,以帮助您与此。

//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文章。

50pmv0ei

50pmv0ei2#

方案一: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在固定的时间、日期或间隔定期运行任务。但corn唯一的缺点是一旦应用程序关闭,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:information
测试cronjob:克朗塔布

snvhrwxg

snvhrwxg3#

使用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),
);

相关问题