如何在Flutter中安排后台任务?

时间:2018-08-06 11:09:57

标签: dart flutter flutter-dependencies

我一直在为此寻找很多东西,但是在Flutter中还没有找到任何软件包或安排后台任务的方法。像Android中一样,有WorkManagerAlarmManager

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

(非常令人失望的是,移动框架无法安排后台任务)。

5 个答案:

答案 0 :(得分:4)

您要执行的操作(即跨平台计划)不是Flutter的限制。这是iOS的限制。请参见此SO post中引用的GitHub comment

答案 1 :(得分:3)

有一个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帖子。

答案 2 :(得分:2)

解决方案1: android_alarm_manager是安排后台任务的最佳解决方案。但唯一的缺点仅支持Android。让我们开始吧:

将此插件照常导入项目后,将以下代码添加到您的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插件,包括警报管理器插件本身,则可能有必要告知后台服务如何初始化插件,具体取决于嵌入该应用程序的Android Flutter。

这是通过为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:information

测试cronjob:crontab

答案 3 :(得分:1)

答案 4 :(得分:1)

使用 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-background-job-9bce92f0a21e