workmanager 0.2.2

  • Readme
  • Changelog
  • Example
  • Installing
  • 96

Flutter Workmanager #

pub package Build status #

Flutter WorkManager is a wrapper around Android's WorkManager and iOS' performFetchWithCompletionHandler, effectively enabling headless execution of Dart code in the background.

This is especially useful to run periodic tasks, such as fetching remote data on a regular basis.

This plugin was featured in this Medium blogpost

Installation #

  workmanager: ^0.2.0
flutter pub get
import 'package:workmanager/workmanager.dart';

Platform Setup #

In order for background work to be scheduled correctly you should follow the Android and iOS setup first.

How to use the package? #

See sample folder for a complete working example.
Before registering any task, the WorkManager plugin must be initialized.

void callbackDispatcher() {
  Workmanager.executeTask((task, inputData) {
    print("Native called background task: $backgroundTask"); //simpleTask will be emitted here.
    return Future.value(true);

void main() {
    callbackDispatcher, // The top level function, aka callbackDispatcher
    isInDebugMode: true // If enabled it will post a notification whenever the task is running. Handy for debugging tasks
  Workmanager.registerOneOffTask("1", "simpleTask"); //Android only (see below)

The callbackDispatcher needs to be either a static function or a top level function to be accessible as a Flutter entry point.

Customisation (Android only!) #

Not every Android WorkManager feature is ported.

Two kinds of background tasks can be registered :

  • One off task : runs only once
  • Periodic tasks : runs indefinitely on a regular basis
// One off task registration

// Periodic task registration
    "simplePeriodicTask", \
    // When no frequency is provided the default 15 minutes is set.
    // Minimum frequency is 15 min. Android will automatically change your frequency to 15 min if you have configured a lower frequency.
    frequency: Duration(hours: 1),

Each task must have an unique name;
This allows cancellation of a started task.
The second parameter is the String that will be send to your callbackDispatcher function, indicating the task's type.

Tagging #

You can set the optional tag property.
Handy for cancellation by tag.
This is different from the unique name in that you can group multiple tasks under one tag.

Workmanager.registerOneOffTask("1", "simpleTask", tag: "tag");

Existing Work Policy #

Indicates the desired behaviour when the same task is scheduled more than once.
The default is KEEP

Workmanager.registerOneOffTask("1", "simpleTask", existingWorkPolicy: ExistingWorkPolicy.append);

Initial Delay #

Indicates how along a task should waitbefore its first run.

Workmanager.registerOneOffTask("1", "simpleTask", initialDelay: Duration(seconds: 10));

Constraints #

Not all constraints are mapped.

    constraints: Constraints(
        networkType: NetworkType.connected,
        requiresBatteryNotLow: true,
        requiresCharging: true,
        requiresDeviceIdle: true,
        requiresStorageNotLow: true

InputData #

Add some input data for your task. Valid value types are: int, bool, double, String and their list

    inputData: {
    'int': 1,
    'bool': true,
    'double': 1.0,
    'string': 'string',
    'array': [1, 2, 3],

BackoffPolicy #

Indicates the waiting strategy upon task failure.
The default is BackoffPolicy.exponential.
You can also specify the delay.

Workmanager.registerOneOffTask("1", "simpleTask", backoffPolicy: BackoffPolicy.exponential, backoffPolicyDelay: Duration(seconds: 10));

Cancellation #

A task can be cancelled in different ways :

By Tag #

Cancels the task that was previously registered using this Tag, if any.


By Unique Name #


All #


0.2.2 #

  • Android:
    • Fix crash when FlutterEngine would be destroyed twice

0.2.1 #

  • Android:
    • Fix example building
    • Cleanup FlutterEngine when job is stopped or cancelled #140,

0.2.0 #

  • Android:
    • Adding support for the Android v2 embedding.
      See more details in the Android setup guide.

0.1.5 #

  • Android:
    • The result was not correctly mapped to a RETRY when returning false from a background task

0.1.4 #

  • Android:
    • Using Backoff Policy in conjunction with device idle constraint is an illegal action.
      Backoff policy is now nullable in the Android code. See issue #107.

0.1.3 #

  • iOS & Android:
    • Result of BackgroundTaskHandler now correctly returns to background method channel
  • iOS:
    • Invoking iOSPerformFetch method now no longer crashes
    • The iOS example app now implements setPluginRegistrantCallback as described in our docs, making it possible to access other plugins during a backround fetch
    • Dart debug logging is now visible again in Xcode's console

0.1.2 #

  • Android:
    • Added support for inputData

0.1.1 #

  • iOS:
    • Added support for Flutter 1.9.1

0.1.0 #

  • First API stable release
  • Android:
    • Improved debug notification with result message first
    • Updated Installation README
  • iOS:
    • 🐞 Improved debug notification delivery when the app is in the background.
    • Updated Installation README

0.0.15 #

  • iOS: 🐞 Make sure all the implementers plugins are available in the background isolate by registering them first.
    This requires the user to provide us with the generated registry in the AppDelegate
  • iOS: 📝 specified minimum deployment target of iOS 10 (with Swift 4.2)

0.0.14 #

  • iOS performBackgroundFetch now actually works.

0.0.13 #

  • [‼️ BREAKING change] You will need to clear the preferences or re-install the App if you had registered jobs already on Android.
  • Android:
    • Thanks to @vanlooverenkoen
      • 🐞 cancelling all task would have failed before this version
      • 📝 Update documentation to be a bit more clear about the minimum frequency a periodic can be scheduled
    • Better debug notification support:
      • Emoji's to quickly see if a task ran successful
      • Elapsed time
      • Collapsing notifications
    • General Internal API renames to improve readability
  • iOS
    • ⬆️ Separate UserDefaults for the plugin
    • 🐞 Memory leak resources cleanup
    • 🐞 Result mapping Dart -> Swift was wrong
    • Better debug notification support:
      • Emoji's to quickly see if a task ran successful
      • Elapsed time
      • Collapsing notifications

0.0.12 #

  • 🐞 expose setPluginRegistrantCallback to the old rusty Java people

0.0.11 #

  • Better README and docs
    • Everything now refers to the top level callback as the callbackDispatcher
    • Some typo's
    • Link to Medium blog post
  • Adds unit tests to the project since the many issues with enum parsing
    • Fixes an issue with the parsing of the NetworkType
  • Project restructure to a src folder

0.0.10 #

  • I should test a little better before publishing to
    • Fixes all enum parsing issues with ExistingWorkPolicy and BackoffPolicy

0.0.9 #

  • A bugfix were parsing the BackOffPolicy was still wrong.

0.0.8 #

  • A bugfix were parsing of the ExistingWorkPolicy and BackoffPolicy went rogue. Addresses #9

0.0.7 #

  • This version is the first version to support iOS with the help of the Background Fetch API.
    • Only recurring tasks can be scheduled by iOS.
    • If you want to respond to iOS background triggers you should add the extra case Workmanager.iOSBackgroundTask to your switch case.
  • [‼️ BREAKING change]
    • Workmanager.defaultCallbackDispatcher becomes Workmanager.executeTask
  • This version was used as referenced in the Medium blogpost

0.0.6+2 #

  • Fixes a bug in which you could not use other plugins inside a EchoCallbackFunction.
    • Fixes #6

    • Fixes #4

    • [‼️ BREAKING change] A user should extend a custom Application and register it in its AndroidManifest.xml

      class App : FlutterApplication(), PluginRegistry.PluginRegistrantCallback {
          override fun onCreate() {
          override fun registerWith(reg: PluginRegistry?) {
      <manifest xmlns:android=""
          <!-- is an that
               calls FlutterMain.startInitialization(this); in its onCreate method.
               In most cases you can leave this as-is, but you if you want to provide
               additional functionality it is fine to subclass or reimplement
               FlutterApplication and put your custom class here. -->
              android:name=".App" <!-- Replace with .App -->
                  <!-- This keeps the window background of the activity showing
                       until Flutter renders its first frame. It can be removed if
                       there is no splash screen (such as the default splash screen
                       defined in @style/LaunchTheme). -->
                      android:value="true" />
                      <action android:name="android.intent.action.MAIN" />
                      <category android:name="android.intent.category.LAUNCHER" />

0.0.6+1 #

  • This version is the first version to support iOS with the help of the Background Fetch API.
    • Only recurring tasks can be scheduled by iOS.
    • If you want to respond to iOS background triggers you should add the extra case Workmanager.iOSBackgroundTask to your switch case.
  • [‼️ BREAKING change]
    • Workmanager.defaultCallbackDispatcher becomes Workmanager.executeTask

0.0.6 #

  • Expose a WorkManagerHelper to the native.
    • This makes it easier if you also have some native code that wants to schedule the Echo Worker

0.0.5 #

  • The description was too big so you lose points for that too...

0.0.4 #

  • Provide a better description so package scores higher on Pub

0.0.3 #

  • Add Dart documentation

0.0.2 #

  • Remove the need to register a custom Application on Android side. (Everything still works in testing)

0.0.1 #

  • Initial Release:
    • Schedule One off task
    • Schedule Periodic task
      • Fixed delay
    • Initial delay
    • Constraints
      • Support for 1 network type
      • requires battery not low
      • requires charging
      • requires device idle
      • requires storage not low
    • back off policy


import 'dart:async';
import 'dart:io';

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

void main() async {

  await Workmanager.initialize(callbackDispatcher, // The top level function, aka callbackDispatcher
          true // If enabled it will post a notification whenever the task is running. Handy for debugging tasks
  print('init work manager');
  await Workmanager.registerOneOffTask(
    existingWorkPolicy: ExistingWorkPolicy.replace,
//    initialDelay: Duration(seconds: 5),


const simpleTaskKey = "simpleTask";
const simpleDelayedTask = "simpleDelayedTask";
const simplePeriodicTask = "simplePeriodicTask";
const simplePeriodic1HourTask = "simplePeriodic1HourTask";

void callbackDispatcher() {
  Workmanager.executeTask((task, inputData) {
    Timer.periodic(Duration(seconds: 15), (Timer t) {
      print('message each 15 second');
    print("Native called background task: pusher"); //simpleTask will be emitted here.
    return Future.value(true);

class MyApp extends StatefulWidget {
  _MyAppState createState() => _MyAppState();

enum _Platform { android, ios }

class PlatformEnabledButton extends RaisedButton {
  final _Platform platform;

    @required Widget child,
    @required VoidCallback onPressed,
  })  : assert(child != null, onPressed != null),
            child: child,
                (Platform.isAndroid && platform == || Platform.isIOS && platform == _Platform.ios)
                    ? onPressed
                    : null);

class _MyAppState extends State<MyApp> {
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text("Flutter WorkManager Example"),
        body: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: <Widget>[
              Text("Plugin initialization", style: Theme.of(context).textTheme.headline),
                  child: Text("Start the Flutter background service"),
                  onPressed: () {
                      isInDebugMode: true,
              SizedBox(height: 16),
              Text("One Off Tasks (Android only)", style: Theme.of(context).textTheme.headline),
              //This task runs once.
              //Most likely this will trigger immediately
                  child: Text("Register OneOff Task"),
                  onPressed: () {
                      inputData: <String, dynamic>{
                        'int': 1,
                        'bool': true,
                        'double': 1.0,
                        'string': 'string',
                        'array': [1, 2, 3],
              //This task runs once
              //This wait at least 10 seconds before running
                  child: Text("Register Delayed OneOff Task"),
                  onPressed: () {
                      initialDelay: Duration(seconds: 10),
              SizedBox(height: 8),
              Text("Periodic Tasks (Android only)", style: Theme.of(context).textTheme.headline),
              //This task runs periodically
              //It will wait at least 10 seconds before its first launch
              //Since we have not provided a frequency it will be the default 15 minutes
                  child: Text("Register Periodic Task"),
                  onPressed: () {
                      initialDelay: Duration(seconds: 10),
              //This task runs periodically
              //It will run about every hour
                  child: Text("Register 1 hour Periodic Task"),
                  onPressed: () {
                      frequency: Duration(hours: 1),
                child: Text("Cancel All"),
                onPressed: () async {
                  await Workmanager.cancelAll();
                  print('Cancel all tasks completed');

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:

  workmanager: ^0.2.2

2. Install it

You can install packages from the command line:

with Flutter:

$ flutter pub get

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:

import 'package:workmanager/workmanager.dart';
Describes how popular the package is relative to other packages. [more]
Code health derived from static analysis. [more]
Reflects how tidy and up-to-date the package is. [more]
Weighted score of the above. [more]
Learn more about scoring.

We analyzed this package on Mar 27, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.7.1
  • pana: 0.13.6
  • Flutter: 1.12.13+hotfix.8

Health suggestions

Format lib/src/workmanager.dart.

Run flutter format to format lib/src/workmanager.dart.


Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.5.0 <3.0.0
flutter 0.0.0
Transitive dependencies
collection 1.14.11 1.14.12
meta 1.1.8
sky_engine 0.0.99
typed_data 1.1.6
vector_math 2.0.8
Dev dependencies
test ^1.9.4