Flutter后台定时任务(BackgroundFetch)

应用场景之一,免费电子书退出app后,后台定时从web爬取小说最新内容实现自动更新!

这里使用的是一个开源软件BackgroundFetch。BackgroundFetch的sample代码中没有太多解析,所以看起来有写费劲,这里就例子做简要说明。

BackgroundFetch其实可以分为两部分,一部分是APP退出后在后台运行的叫做HeadlessTask,一个是进入APP后再后台运行的,叫BackgroundFetch。对于sample中的代码,我们把它划分成两部分来看就简单了。

  1. HeadlessTask
    这部分任务是在APP退出后周期性运行的,代码中配置如下:
import 'package:background_fetch/background_fetch.dart';

/// This "Headless Task" is run when app is terminated.
void backgroundFetchHeadlessTask(String taskId) async {
  DateTime timestamp = DateTime.now();
  print("[BackgroundFetch] Headless event received: $taskId@$timestamp");
  BackgroundFetch.finish(taskId);

  if (taskId == 'flutter_background_fetch') {
    await AutoRefresh.fetchAndUpdateAllBooks();
  }
}

void main() {
  runApp(MyApp());
  // Register to receive BackgroundFetch events after app is terminated.
  // Requires {stopOnTerminate: false, enableHeadless: true}
  BackgroundFetch.registerHeadlessTask(backgroundFetchHeadlessTask);
}

flutter_background_fetch是BackgroundFetch默认的TaskID(的名称),只要运行BackgroundFetch,默认就有个taskid = flutter_background_fetch的任务在运行(这涉及到BackgroundFetch的配置,可以看下节)。运行的间隔时间由下届=节中提到的初始config决定,一般在Android时间比较准确,IOS中由于平台的运行,可能不是很准。
代码说明:main中注册HeadlessTask,然后实际运行时就会跑backgroundFetchHeadlessTask,默认taskid为flutter_background_fetch。代码中的AutoRefresh.fetchAndUpdateAllBooks()就是我项目中对电子书的刷新。

  1. BackgroundFetch
    这部分task则是进入app后,在后台运行的,看代码:
  @override
  void initState() {
    super.initState();
    loadData();
    initPlatformState();
  }

  Future<void> initPlatformState() async {
    BackgroundFetch.configure(BackgroundFetchConfig(
      minimumFetchInterval: 60,
      forceAlarmManager: true,
      stopOnTerminate: false,
      startOnBoot: true,
      enableHeadless: true,
      requiresBatteryNotLow: true,
      requiresCharging: false,
      requiresStorageNotLow: true,
      requiresDeviceIdle: false,
      requiredNetworkType: NetworkType.UNMETERED,
    ), _onBackgroundFetch).then((int status){
      print('[BackgroundFetch] configure success: $status');
    }).catchError((e) {
      print('[BackgroundFetch] configure ERROR: $e');
    });

    /*BackgroundFetch.scheduleTask(TaskConfig(
        taskId: "com.transistorsoft.customtask",
        delay: 10000,
        periodic: false,
        forceAlarmManager: true,
        stopOnTerminate: false,
        enableHeadless: true
    ));*/
  }

  void _onBackgroundFetch(String taskId) async {
    DateTime timestamp = DateTime.now();
    print("[BackgroundFetch] Event received: $taskId@$timestamp");

    if (taskId == "flutter_background_fetch") {
      // Schedule a one-shot task when fetch event received (for testing).
      BackgroundFetch.scheduleTask(TaskConfig(
          taskId: "com.transistorsoft.customtask",
          delay: 5000,
          periodic: false,
          forceAlarmManager: true,
          stopOnTerminate: false,
          enableHeadless: true
      ));
    }

    // IMPORTANT:  You must signal completion of your fetch task or the OS can punish your app
    // for taking too long in the background.
    BackgroundFetch.finish(taskId);
  }

BackgroundFetch.configure就是对默认任务flutter_background_fetch的配置, minimumFetchInterval就是时间间隔,APP运行的情况下,对任务flutter_background_fetch的处理函数是configure中的_onBackgroundFetch,例如上述代码,每隔1个小时就会调用一次_onBackgroundFetch, 而当APP退出后,每隔一个小时,会跑一次backgroundFetchHeadlessTask。代码中的BackgroundFetch.scheduleTask是自定义的任务。

  1. 总结
    一直在找可以实现后台定时任务的的Dart API,目前只找到这个,问题暂时没发现。

你可能感兴趣的:(flutter&react,flutter)