Flutter后台任务执行插件background_fetch的使用
Flutter background_fetch 插件使用指南
简介
background_fetch
是一个Flutter插件,用于在应用程序处于后台时定期唤醒应用执行一些简短的任务。它会每隔15分钟左右唤醒一次应用,允许您提供一个回调函数 callbackFn
来处理这些背景事件。
iOS 注意事项
- 无法增加获取事件发生的频率,并且当用户长时间未打开设备或应用程序时,iOS会减少获取事件的发生频率。
- 当应用程序被终止后,iOS将不再触发事件,因此不存在
stopOnTerminate: false
的情况。 scheduleTask
方法似乎只在设备插入电源时触发,并且该方法设计用于低优先级任务,不会如预期般频繁运行。
Android 注意事项
- 提供了Headless实现,允许在应用程序终止后继续处理事件。
安装插件
在项目的 pubspec.yaml
文件中添加依赖:
dependencies:
background_fetch: '^1.1.3'
或者从GitHub上安装最新版本:
dependencies:
background_fetch:
git:
url: https://github.com/transistorsoft/flutter_background_fetch
示例代码
下面是一个完整的示例程序,展示了如何配置和使用 background_fetch
插件。
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:background_fetch/background_fetch.dart';
// [Android-only] 当应用程序被终止时,此“无头任务”会被执行
void backgroundFetchHeadlessTask(HeadlessTask task) async {
String taskId = task.taskId;
bool isTimeout = task.timeout;
if (isTimeout) {
print("[BackgroundFetch] Headless task timed-out: $taskId");
BackgroundFetch.finish(taskId);
return;
}
print('[BackgroundFetch] Headless event received.');
// 在这里执行你的工作...
BackgroundFetch.finish(taskId);
}
void main() {
runApp(new MyApp());
// 注册接收应用程序终止后的 BackgroundFetch 事件
BackgroundFetch.registerHeadlessTask(backgroundFetchHeadlessTask);
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
bool _enabled = true;
int _status = 0;
List<DateTime> _events = [];
@override
void initState() {
super.initState();
initPlatformState();
}
Future<void> initPlatformState() async {
// 配置 BackgroundFetch.
int status = await BackgroundFetch.configure(
BackgroundFetchConfig(
minimumFetchInterval: 15,
stopOnTerminate: false,
enableHeadless: true,
requiresBatteryNotLow: false,
requiresCharging: false,
requiresStorageNotLow: false,
requiresDeviceIdle: false,
requiredNetworkType: NetworkType.NONE,
),
(String taskId) async {
print("[BackgroundFetch] Event received $taskId");
setState(() {
_events.insert(0, DateTime.now());
});
BackgroundFetch.finish(taskId);
},
(String taskId) async {
print("[BackgroundFetch] TASK TIMEOUT taskId: $taskId");
BackgroundFetch.finish(taskId);
},
);
print('[BackgroundFetch] configure success: $status');
setState(() {
_status = status;
});
if (!mounted) return;
}
void _onClickEnable(bool enabled) {
setState(() {
_enabled = enabled;
});
if (enabled) {
BackgroundFetch.start().then((int status) {
print('[BackgroundFetch] start success: $status');
}).catchError((e) {
print('[BackgroundFetch] start FAILURE: $e');
});
} else {
BackgroundFetch.stop().then((int status) {
print('[BackgroundFetch] stop success: $status');
});
}
}
void _onClickStatus() async {
int status = await BackgroundFetch.status;
print('[BackgroundFetch] status: $status');
setState(() {
_status = status;
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('BackgroundFetch Example', style: TextStyle(color: Colors.black)),
backgroundColor: Colors.amberAccent,
brightness: Brightness.light,
actions: <Widget>[
Switch(value: _enabled, onChanged: _onClickEnable),
],
),
body: Container(
color: Colors.black,
child: ListView.builder(
itemCount: _events.length,
itemBuilder: (BuildContext context, int index) {
DateTime timestamp = _events[index];
return InputDecorator(
decoration: InputDecoration(
contentPadding: EdgeInsets.only(left: 10.0, top: 10.0, bottom: 0.0),
labelStyle: TextStyle(color: Colors.amberAccent, fontSize: 20.0),
labelText: "[background fetch event]",
),
child: Text(timestamp.toString(), style: TextStyle(color: Colors.white, fontSize: 16.0)),
);
}),
),
bottomNavigationBar: BottomAppBar(
child: Row(
children: <Widget>[
RaisedButton(onPressed: _onClickStatus, child: Text('Status')),
Container(child: Text("$_status"), margin: EdgeInsets.only(left: 20.0))
],
),
),
),
);
}
}
执行自定义任务
除了默认的背景获取任务外,还可以通过 scheduleTask
方法安排一次性或周期性的任务。需要注意的是,在iOS上,scheduleTask
只有在设备充电时才会运行,并且设计为低优先级任务,不能保证按需频繁运行。
// Step 1: Configure BackgroundFetch as usual.
int status = await BackgroundFetch.configure(
BackgroundFetchConfig(
minimumFetchInterval: 15,
),
(String taskId) async {
print("[BackgroundFetch] taskId: $taskId");
switch (taskId) {
case 'com.transistorsoft.customtask':
print("Received custom task");
break;
default:
print("Default fetch task");
}
BackgroundFetch.finish(taskId);
},
(String taskId) async {
print("[BackgroundFetch] TIMEOUT taskId: $taskId");
BackgroundFetch.finish(taskId);
},
);
// Step 2: Schedule a custom "oneshot" task "com.transistorsoft.customtask" to execute 5000ms from now.
BackgroundFetch.scheduleTask(TaskConfig(
taskId: "com.transistorsoft.customtask",
delay: 5000, // milliseconds
));
调试
对于iOS,可以通过Xcode模拟器来测试背景任务是否正常工作。而对于Android,则可以使用adb命令行工具查看日志或模拟事件。
更多详细信息请参阅官方文档和其他相关资源链接。
更多关于Flutter后台任务执行插件background_fetch的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter后台任务执行插件background_fetch的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter应用中使用background_fetch
插件来执行后台任务的示例代码。这个插件允许应用在后台定期执行某些任务,例如获取位置更新、同步数据等。
首先,确保你已经将background_fetch
插件添加到你的Flutter项目中。你可以在pubspec.yaml
文件中添加以下依赖:
dependencies:
flutter:
sdk: flutter
background_fetch: ^0.x.x # 请使用最新版本号
然后,运行flutter pub get
来安装依赖。
接下来,在你的Flutter项目中,你需要配置并启动后台任务。以下是一个完整的示例:
- 在
main.dart
文件中配置background_fetch
:
import 'package:flutter/material.dart';
import 'package:background_fetch/background_fetch.dart';
void main() {
runApp(MyApp());
configureBackgroundFetch();
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Background Fetch Example'),
),
body: Center(
child: Text('Check the console for background fetch logs.'),
),
),
);
}
}
void configureBackgroundFetch() async {
// 等待背景任务完成配置
BackgroundFetch.configure(
MinimumFetchInterval.FIFTEEN_MINUTES,
enableHeadless: true,
stopOnTerminate: false,
requiresBatteryNotLow: false,
requiresCharging: false,
requiresStorageNotLow: false,
requiresDeviceIdle: false,
jobId: 'com.example.backgroundfetch',
onReceive: (taskId) async {
// 这里执行后台任务
print("[BackgroundFetch] taskId: $taskId");
// 模拟任务执行(例如,获取位置)
await performBackgroundTask();
// 完成任务后必须调用finish
BackgroundFetch.finish(taskId);
},
).then((String status) {
print("[BackgroundFetch] configure success: $status");
}).catchError((error) {
print("[BackgroundFetch] configure ERROR: $error");
});
}
Future<void> performBackgroundTask() async {
// 这里放置你的后台任务逻辑
// 例如,获取位置、同步数据等
await Future.delayed(Duration(seconds: 5)); // 模拟任务执行时间
print("[BackgroundTask] Performing background task...");
}
- 配置
AndroidManifest.xml
(如果需要):
确保你的AndroidManifest.xml
文件中有必要的权限,特别是如果你需要访问位置或网络。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.yourapp">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<!-- 其他配置 -->
</manifest>
- 添加Headless Task支持(可选,但推荐):
如果你的后台任务需要在应用未运行时执行(例如,设备重启后),你需要创建一个Headless Task。
创建一个新的Dart文件,例如headless_task.dart
:
import 'package:background_fetch/background_fetch.dart';
void headlessTask(String taskId) async {
print("[HeadlessTask] taskId: $taskId");
// 执行你的后台任务逻辑
await performBackgroundTask();
// 完成任务后必须调用finish
BackgroundFetch.finish(taskId);
}
然后在你的main.dart
文件中注册这个Headless Task:
void main() {
BackgroundFetch.registerHeadlessTask(headlessTask);
runApp(MyApp());
configureBackgroundFetch();
}
这个示例展示了如何在Flutter应用中使用background_fetch
插件来配置和执行后台任务。请注意,后台任务的执行频率和可靠性可能受到操作系统和设备设置的影响,因此在实际应用中可能需要进一步的测试和调优。