Flutter: Perform Background Job

Jitesh Mohite
FlutterWorld
Published in
3 min readFeb 13, 2021

--

Every application does some kind of background work which required to be performed for data storage, API usage, hardware events many more. In this article, we will learn about scheduling background tasks in our flutter apps using one of the simplest methods.

Please find below steps to use workmanager plugin

1. Depend on it

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

dependencies:
workmanager: ^0.2.3

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';

WorkManager comes under two parts, which run the task in the background.

1. Delayed background work

registerOneOffTask runs the task only once with an initial delay of 10 seconds. This is useful when we need to perform any background work only once.

Example:

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

2. Periodic background work

This task runs periodically, Since we have not provided a frequency it will be the default 15 minutes.

Example:

Workmanager.registerPeriodicTask(
"2",
"registerPeriodicTask",
initialDelay: Duration(seconds: 10),
);

If we provide the frequency of 1 hour then it will run background job after every one hour. Likewise, we can mention different frequencies but it should be more than 15 minutes.

frequency: Duration(hours: 1),

The next thing we have to do initialize is callbackDispatcher, so what is this?

CallbackDispactcher is invoked inside flutter code, so to perform anything inside Flutter, we do require Flutter Engine to be available. callbackDispatcher is a dart callback function that gets called only when native code(iOS/Android) invokes any background work. Just one thing we have to remember before using it is that callbackDispatcher method must be a top-level function or a static block of code.

Workmanager.initialize(
callbackDispatcher, // The top level function, aka callbackDispatcher
isInDebugMode: false // This should be false
);

The above code should be implemented inside main() method, for better understanding goes through the below code.

Full Code:

The below code runs the background job after every 15 minutes and saved the incremented value in shared preference.

import 'dart:async';

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

const String TAG = "BackGround_Work";

void main() {
WidgetsFlutterBinding.ensureInitialized();
Workmanager.initialize(
callbackDispatcher, // The top level function, aka callbackDispatcher
isInDebugMode: false // This should be false
);
runApp(MyApp());
}

class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'BackGround Work Sample',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: BackGroundWorkSample(),
);
}
}

class BackGroundWorkSample extends StatefulWidget {
@override
_BackGroundWorkSampleState createState() => _BackGroundWorkSampleState();
}

class _BackGroundWorkSampleState extends State<BackGroundWorkSample> {
int _counterValue = 0;

@override
void initState() {
// TODO: implement initState
super.initState();
//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
Workmanager.registerPeriodicTask(
TAG,
"simplePeriodicTask",
initialDelay: Duration(seconds: 10),
);
loalData();
}

void loalData() async {
_counterValue =
await BackGroundWork.instance._getBackGroundCounterValue();
setState(() {});
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('BackGround Work Sample'),
),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text("Counter Value: ${_counterValue}"),
RaisedButton(onPressed: () {
loalData();
}, child: Text("Fetch Current Counter Value"),)
],
),
));
}
}

void callbackDispatcher() {
Workmanager.executeTask((task, inputData) async {
print(TAG + "callbackDispatcher");
int value =
await BackGroundWork.instance._getBackGroundCounterValue();
BackGroundWork.instance._loadCounterValue(value + 1);
return Future.value(true);
});
}

class BackGroundWork {
BackGroundWork._privateConstructor();

static final BackGroundWork _instance =
BackGroundWork._privateConstructor();

static BackGroundWork get instance => _instance;

_loadCounterValue(int value) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setInt('BackGroundCounterValue', value);
}

Future<int> _getBackGroundCounterValue() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
//Return bool
int counterValue = prefs.getInt('BackGroundCounterValue') ?? 0;
return counterValue;
}
}

Output:

--

--

Jitesh Mohite
FlutterWorld

I am technology enthusiastic, want to learn things quickly and dive deep inside it. I always believe in developing logical things which makes impact on end user