-
Notifications
You must be signed in to change notification settings - Fork 0
Usage of Workmanager in React Native
WorkManager allows us to run background tasks reliably, even when the app is not running or the device is restarted. In the context of React Native, this enables powerful background capabilities such as syncing data, scheduling jobs, or processing tasks without needing the app to be actively open.
With the right setup, we can configure WorkManager to trigger and execute custom JavaScript functions in React Native β enabling true background sync and logic execution, independent of the appβs foreground state.
At the heart of the background sync logic is the BackgroundSyncWorker
class, which extends a custom HeadlessWorker
. This worker is triggered by Android's WorkManager and is responsible for setting up and executing JavaScript tasks, even when the app is terminated.
This method is the core of the worker. It tells React Native what task to run and how to run it.
override fun getTaskConfig(data: Data?): HeadlessJsTaskConfig?
-
It receives a
Data
object from WorkManager that contains all the necessary task parameters. -
This data is then parsed into:
-
taskKey
: Identifier of the JavaScript task to run. -
maxRetryAttempts
: Number of times to retry the task on failure. -
retryDelay
: Delay (in ms) between retries. -
taskTimeout
: Timeout for the JS task (after which it's considered failed). -
allowedInForeground
: Whether this task is allowed to run while the app is in the foreground.
-
A retry policy is configured using LinearCountingRetryPolicy
, which will retry the JS task a specified number of times with a fixed delay.
val retryPolicy: HeadlessJsTaskRetryPolicy = LinearCountingRetryPolicy(
maxRetryAttempts,
retryDelay,
)
The HeadlessJsTaskConfig
tells React Native which task to execute and includes all the runtime options like timeout, retry behavior, and whether it can run in the foreground.
return HeadlessJsTaskConfig(
taskKey,
Arguments.makeNativeMap(data.keyValueMap),
taskTimeout,
allowedInForeground,
retryPolicy
)
When running background tasks via WorkManager, JavaScript code is executed in a headless context β meaning it runs without the app UI or React component tree. This is powerful but requires following certain rules to avoid runtime errors and ensure reliable execution.
-
Use Pure Functions or Independent Logic
Write self-contained logic that does not rely on React components, hooks, or app state.// tasks/backgroundSync.js export default async function backgroundSyncTask(data) { const response = await fetch('https://example.com/api/sync'); const json = await response.json(); // Save data to storage/database }
-
Use Async/Await or Promises
The function should return a Promise so the native layer knows when it completes. -
Handle Errors Gracefully
Always wrap logic intry/catch
to handle failures and avoid crashes. -
Use Lightweight, Non-UI Libraries
You can use libraries likeaxios
,date-fns
,AsyncStorage
, etc.
Avoid anything that relies on the UI or user interaction. -
Access Native Modules
You can useNativeModules
and call any native methods registered to the bridge.
However, ensure that these native modules do not trigger any UI operations or navigation.
-
Do Not Use React Hooks (
useEffect
,useState
, etc.)
Hooks depend on the React rendering lifecycle, which is not available in a headless JS context. -
Avoid Importing UI Components
No<View>
,<Text>
, or custom screens β there is no UI to display. -
Do Not Use Navigation or Routing
You cannot triggerreact-navigation
actions or navigate screens. -
Avoid UI-bound State Managers
Hooks likeuseSelector
oruseDispatch
won't work.
If needed, use raw Redux store logic without the React bindings. -
Avoid Long-Running or Heavy Tasks
Android may terminate long or CPU-intensive tasks. Keep your logic quick and efficient. -
Avoid UI Timing APIs (
setTimeout
,setInterval
, etc.)
These may not behave reliably in a background context and can cause your task to stall or crash.
Use promise-based timing (await new Promise
) if absolutely necessary β and keep durations short.