Пример фоновой выборки Flutter WorkManager с виджетом StateFull

У меня есть функция под названием control в виджете StateFull. Я хочу запускать эту функцию с WorkManager каждые 15 минут.

Как я могу вызвать функцию управления из функции 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);
  });
}

1 ответ

Для тех, кто все еще ищет ответ:

Из официальных документов:

CallbackDispatcher должен быть либо статической функцией, либо функцией верхнего уровня, чтобы быть доступным в качестве точки входа Flutter.

У меня была такая же проблема, и я решил ее, переместив функцию в файл: main.dart

Кроме того, код, который инициализирует callbackDispatcherдолжен быть в main()перед App()виджет загружается.

Чтобы вызвать свой управляющий код, создайте класс со статической функцией control()

Примечание. Вы не можете вызывать метод виджета из callbackDispatcher!

Причина: виджеты привязаны к пользовательскому интерфейсу. Пока экран остается активным, видимый виджет остается активным. Как только вы закрываете приложение или переходите к следующему экрану, память виджетов перерабатывается. Но этот callbackDispatcher выполняется, даже когда ваше приложение закрыто. Таким образом, он должен быть изолирован от кода пользовательского интерфейса.

Вот код:

основной.дротик:

      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 минут.

Другие вопросы по тегам