• Stars
    star
    841
  • Rank 54,194 (Top 2 %)
  • Language
    Dart
  • Created over 5 years ago
  • Updated 3 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A Flutter plugin which allows you to execute code in the background on Android and iOS.

Flutter Workmanager

pub package Build status

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

For iOS users, please watch this video on a general introduction to background processing: https://developer.apple.com/videos/play/wwdc2020/10063. All of the constraints discussed in the video also apply to this plugin.

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

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.

@pragma('vm:entry-point') // Mandatory if the App is obfuscated or using Flutter 3.1+
void callbackDispatcher() {
  Workmanager().executeTask((task, inputData) {
    print("Native called background task: $backgroundTask"); //simpleTask will be emitted here.
    return Future.value(true);
  });
}

void main() {
  Workmanager().initialize(
    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("task-identifier", "simpleTask");
  runApp(MyApp());
}

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

The workmanager runs on a separate isolate from the main flutter isolate. Ensure to initialize all dependencies inside the Workmanager().executeTask.

Debugging tips

Wrap the code inside your Workmanager().executeTask in a try and catch in order to catch any exceptions thrown.

@pragma('vm:entry-point')
void callbackDispatcher() {
  Workmanager().executeTask((task, inputData) {

    int? totalExecutions;
    final _sharedPreference = await SharedPreferences.getInstance(); //Initialize dependency

    try { //add code execution
      totalExecutions = _sharedPreference.getInt("totalExecutions");
      _sharedPreference.setInt("totalExecutions", totalExecutions == null ? 1 : totalExecutions+1);
    } catch(err) {
      Logger().e(err.toString()); // Logger flutter package, prints error on the debug console
      throw Exception(err);
    }

    return Future.value(true);
  });
}

Android tasks are identified using their taskName. iOS tasks are identitied using their taskIdentifier.

However, there is an exception for iOS background fetch: Workmanager.iOSBackgroundTask, a constant for iOS background fetch task.


Work Result

The Workmanager().executeTask(... block supports 3 possible outcomes:

  1. Future.value(true): The task is successful.
  2. Future.value(false): The task did not complete successfully and needs to be retried. On Android, the retry is done automatically. On iOS (when using BGTaskScheduler), the retry needs to be scheduled manually.
  3. Future.error(...): The task failed.

On Android, the BackoffPolicy will configure how WorkManager is going to retry the task.

Refer to the example app for a successful, retrying and a failed task.

iOS specific setup and note

iOS supports One off tasks with a few basic constraints:

Workmanager().registerOneOffTask(
  "task-identifier",
  simpleTaskKey, // Ignored on iOS
  initialDelay: Duration(minutes: 30),
  constraints: Constraints(
    // connected or metered mark the task as requiring internet
    networkType: NetworkType.connected,
    // require external power
    requiresCharging: true,
  ),
  inputData: ... // fully supported
);

For more information see the BGTaskScheduler documentation.

Customisation (Android)

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
Workmanager().registerOneOffTask(
    "oneoff-task-identifier", 
    "simpleTask"
);

// Periodic task registration
Workmanager().registerPeriodicTask(
    "periodic-task-identifier", 
    "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 sent 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

Constraints are mapped at best effort to each platform. Android's WorkManager supports most of the specific constraints, whereas iOS tasks are limited.

  • NetworkType Constrains the type of network required for your work to run. For example, Connected. The NetworkType lists various network conditions. .connected & .metered will be mapped to requiresNetworkConnectivity on iOS.
  • RequiresBatteryNotLow (Android only) When set to true, your work will not run if the device is in low battery mode. Enabling the battery saving mode on the android device prevents the job from running
  • RequiresCharging When set to true, your work will only run when the device is charging.
  • RequiresDeviceIdle (Android only) When set to true, this requires the user’s device to be idle before the work will run. This can be useful for running batched operations that might otherwise have a - negative performance impact on other apps running actively on the user’s device.
  • RequiresStorageNotLow (Android only) When set to true, your work will not run if the user’s storage space on the device is too low.
Workmanager().registerOneOffTask(
    "1",
    "simpleTask",
    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

 Workmanager().registerOneOffTask(
    "1",
    "simpleTask",
    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.

Workmanager().cancelByTag("tag");

By Unique Name

Workmanager().cancelByUniqueName("<MyTask>");

All

Workmanager().cancelAll();

More Repositories

1

flutter_launcher_icons

Flutter Launcher Icons - A package which simplifies the task of updating your Flutter app's launcher icon. Fully flexible, allowing you to choose what platform you wish to update the launcher icon for and if you want, the option to keep your old launcher icon in case you want to revert back sometime in the future. Maintainer: @MarkOSullivan94
Dart
1,986
star
2

chewie

The video player for Flutter with a heart of gold
Dart
1,940
star
3

community

Flutter Community - A central place for community made Flutter content.
1,558
star
4

plus_plugins

Flutter Community Plus Plugins
Dart
1,554
star
5

flutter_webview_plugin

Community WebView Plugin - Allows Flutter to communicate with a native WebView.
Java
1,480
star
6

get_it

Get It - Simple direct Service Locator that allows to decouple the interface from a concrete implementation and to access the concrete implementation from everywhere in your App. Maintainer: @escamoteur
Dart
1,323
star
7

flutter_sticky_headers

Flutter Sticky Headers - Lets you place "sticky headers" into any scrollable content in your Flutter app. No special wrappers or magic required. Maintainer: @slightfoot
Dart
1,075
star
8

flutter_downloader

Flutter Downloader - A plugin for creating and managing download tasks.
Kotlin
913
star
9

font_awesome_flutter

The Font Awesome Icon pack available as Flutter Icons
Dart
835
star
10

flutter_blurhash

Compact representation of a placeholder for an image. Encode a blurry image under 30 caracters for instant display like used by Medium. Maintainer: @Solido
Dart
523
star
11

redux.dart

Redux for Dart
Dart
515
star
12

flutter_after_layout

Flutter After Layout - Brings functionality to execute code after the first layout of a widget has been performed, i.e. after the first frame has been displayed. Maintainer: @slightfoot
Dart
476
star
13

flutter-draggable-scrollbar

Draggable Scrollbar - A scrollbar that can be dragged for quickly navigation through a vertical list. Additional option is showing label next to scrollthumb with information about current item. Maintainer: @marica27
Dart
442
star
14

responsive_scaffold

Responsive Scaffold - On mobile it shows a list and pushes to details and on tablet it shows the List and the selected item. Maintainer: @rodydavis
Dart
362
star
15

app_review

App Review - Request and Write Reviews and Open Store Listing for Android and iOS in Flutter. Maintainer: @rodydavis
Dart
333
star
16

backdrop

Backdrop implementation in flutter.
Dart
328
star
17

flutter_infinite_listview

Flutter Infinite ListView - ListView with items that can be scrolled infinitely in both directions. Maintainer: @slightfoot
Dart
306
star
18

flutter_google_places

Google Places - Google places autocomplete widgets for flutter. No wrapper, use https://pub.dev/packages/google_maps_webservice. Maintainer: @juliansteenbakker
Dart
303
star
19

flutter_sms

A Flutter plugin to Send SMS and MMS on iOS and Android. If iMessage is enabled it will send as iMessage on iOS. This plugin must be tested on a real device on iOS. Maintainer: @rodydavis
Dart
245
star
20

flutter_uploader

background upload plugin for flutter
Dart
211
star
21

page_turn

Page Turn Widget - Add a page turn effect to widgets in your app. Maintainer: @rodydavis
Dart
194
star
22

import_sorter

🎯 Automatically organize your dart imports. Maintainer: @gleich
Dart
169
star
23

flutter_contacts

Contacts Service - A Flutter plugin to retrieve and manage contacts on Android and iOS devices. Maintainer: @lukasgit
Java
153
star
24

flutter_wear_plugin

A plugin that offers widgets for Wear OS by Google
Dart
135
star
25

rx_command

RxCommand - Reactive event handler wrapper class inspired by ReactiveUI. Maintainer @escamoteur
Dart
134
star
26

breakpoint

Breakpoint - A Flutter plugin to calculate the material design breakpoints. Maintainer: @rodydavis
Dart
109
star
27

get_version

Get Version - Get the Version Name, Version Code, Platform and OS Version, and App ID on iOS and Android. Maintainer: @rodydavis
Ruby
95
star
28

native_widgets

Native Widgets - A new Flutter package for using Android and iOS natively on each platform. Maintainer: @rodydavis
Dart
92
star
29

state_persistence

State Persistence - Persist state across app launches. By default this library store state as a local JSON file called `data.json` in the applications data directory. Maintainer: @slightfoot
Dart
74
star
30

persist_theme

Persist Theme - A flutter plugin for persisting the theme data. Support for Dark Modes. Maintainer @rodydavis
Dart
69
star
31

wakelock_plus

Flutter plugin that allows you to keep the device screen awake on Android, iOS, macOS, Windows, Linux, and web.
Dart
68
star
32

dart_sealed_unions

Sealed Unions for Dart. Maintainer: @nodinosaur
Dart
66
star
33

flutter-styleguide

Flutter Style Guide. Suggested styles and best practices for teams using Flutter.
49
star
34

firestore_helpers

Firestore Helpers - Firestore helper function to create dynamic and location based queries. Maintainer: @escamoteur
Dart
48
star
35

rocket_guide

An example project for #30DaysOfFlutter.
Dart
34
star
36

android_id

Maintainer: @nohli
Dart
33
star
37

admin_dashboard

Admin Dashboard - a Flutter Community Dashboard that assists admins by rounding up and providing the admins with information regarding issues, latest activities on repositories, maintainers, level of access and a trigger to build and deploy to pub. dev, and more. (Work In Progress)
Dart
24
star
38

arcgis_map_sdk

Flutter implementation of the ArcGis map framework by esri
Dart
12
star
39

interval_tree

A non-overlapping interval tree for Dart
Dart
5
star
40

redux_undo

Redux Undo - Make your redux store undo- and redoable. Inspired by the JS redux_undo package. Maintainer: @michelengelen
Dart
5
star
41

transfer-guide

The official Flutter Community Transfer Guide for package maintainers wanting to transfer their package to the organization.
5
star
42

site

Website
Dart
4
star
43

readme_generator

A Dart program that generates the README.md for the FlutterCommunity/community repo.
Dart
3
star
44

fluttercommunity.github.io

The Flutter Community website.
HTML
1
star