【问题标题】:Flutter WorkManager Background Fetch Example With StateFull Widget带有 StateFull 小部件的 Flutter WorkManager 后台获取示例
【发布时间】:2021-04-14 10:54:08
【问题描述】:

我在 StateFull Widget 中有一个名为 control 的函数。我想每 15 分钟用 WorkManager 运行一次这个函数。

如何从 callbackDispatcher 函数调用控制函数? 我将 Stream 静态添加到 Statefull 小部件,然后收听了它,但它不起作用。

HomeScreen.dart 文件

import 'package:flutter/material.dart';
import 'package:workmanager/workmanager.dart';

const taskKontrol = "control";

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  @override
  Widget build(BuildContext context) {
    return Container();
  }

  @override
  void initState() {
    super.initState();
    setupWorkManager();
  }

  void control() async
  {
    //... my code control is here
  }

}

void setupWorkManager() async {
  await Workmanager.initialize(callbackDispatcher, isInDebugMode: true);
  Workmanager.registerPeriodicTask(taskKontrol, taskKontrol,
      frequency: Duration(seconds: 10),
      existingWorkPolicy: ExistingWorkPolicy.append
  );
}


void callbackDispatcher() {
  Workmanager.executeTask((taskName, inputData) async {
    switch(taskName)
    {
      case taskKontrol:
        // How can I call the control function from here?
        print("control from workmanager");
        break;
    }
    return Future.value(true);
  });
}

【问题讨论】:

  • 要向 Workmanager 发送数据以及从 Workmanager 发送数据,您需要 Isolates。 medium.com/dartlang/…

标签: flutter background-fetch flutter-workmanager


【解决方案1】:

对于那些仍在寻找答案的人:

来自official docs:

callbackDispatcher 必须是静态函数或顶级函数才能作为 Flutter 入口点访问。

我遇到了同样的问题,我通过将函数 callbackDispatcher 移动到文件中解决了它:main.dart

另外,初始化callbackDispatcher 的代码必须在App() 小部件加载之前位于main()

要调用您的控制代码,请使用静态函数 control() 创建一个类

注意:您不能从 callbackDispatcher 调用小部件的方法!

原因:小部件是 UI 绑定的。只要屏幕保持活动状态,可见的小部件就会保持活动状态。一旦您关闭应用程序或移至下一个屏幕,小部件的内存就会被回收。但是即使您的应用程序关闭,这个 callbackDispatcher 也会被执行。因此,它必须与 UI 代码隔离。

代码如下:

main.dart:

import 'package:flutter/material.dart';
import 'package:workmanager/workmanager.dart';


void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Workmanager().initialize(callbackDispatcher, isInDebugMode: true);
  runApp(App());
}

void callbackDispatcher() {
  Workmanager.executeTask((taskName, inputData) async {
    switch(taskName)
    {
      case ScheduledTask.taskName:
        ScheduledTask.control(); // calls your control code
        break;
    }
    return Future.value(true);
  });
}

class ScheduledTask {
  const static String taskName = "control";
  static void control() {
    // add your control here
  }
}

您可以通过 HomeScreen 小部件执行的所有操作就是调用安排任务的 setupWorkManager()

class _HomeScreenState extends State<HomeScreen> {
  @override
  Widget build(BuildContext context) {
    return Container();
  }

  @override
  void initState() {
    super.initState();
    setupWorkManager();
  }
}

void setupWorkManager() async {
  Workmanager.registerPeriodicTask(taskKontrol, taskKontrol,
      frequency: Duration(minutes: 15),
      existingWorkPolicy: ExistingWorkPolicy.append
  );
}

注意:重复任务的最低频率为 15 分钟

【讨论】:

    猜你喜欢
    • 2022-11-27
    • 2019-08-09
    • 2021-11-21
    • 2021-06-07
    • 2020-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-11
    相关资源
    最近更新 更多