我一直在寻找这个,但没有找到任何包或在 Flutter 中安排后台任务的方法。就像在 Android 中一样,有WorkManager
, AlarmManager
。
我知道我可以使用 访问这些类MethodChannel
,但我想要一些适用于 iOS 和 Android 的东西。
(移动框架没有调度后台任务的能力非常令人失望)。
我一直在寻找这个,但没有找到任何包或在 Flutter 中安排后台任务的方法。就像在 Android 中一样,有WorkManager
, AlarmManager
。
我知道我可以使用 访问这些类MethodChannel
,但我想要一些适用于 iOS 和 Android 的东西。
(移动框架没有调度后台任务的能力非常令人失望)。
有一篇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帖子。
解决方案 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
使用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