---
title: Troubleshooting: Tasks Stopping After App Close
description: Why background tasks stop when the app is closed and how to fix it (OEM battery optimization, constraints, verification)
---

This is the most-reported issue for background task plugins, and almost always
the operating system - not the plugin - deciding not to run your task. This
guide explains what is happening, how to fix it per Android OEM, and how to
prove whether you have a genuine bug worth reporting.

## The short version

- **Android**: WorkManager schedules *persistent deferred work*. A correctly
  configured Android device runs it even after the app process is killed.
  Aggressive OEM battery managers (Xiaomi, Huawei, OPPO, OnePlus, Vivo,
  Samsung, ...) and Doze routinely defer or block execution until the next
  app launch. No plugin can override the OEM's battery manager.
- **iOS**: apps that the user explicitly terminates get **no** background
  execution until they are relaunched. BGTaskScheduler work only runs when
  iOS decides to, and processing tasks require the device to be idle.
- The plugin's job is registration + callback execution. **When** a task runs
  is entirely the OS's decision.

Before going further: if your task *never* runs on a current version with
battery optimization disabled and a fresh install (first run + one closed-state
cycle), with `adb logcat` / device logs attached, that would be a genuine bug
worth reporting. Everything else is OS scheduling behavior.

## Android: OEM battery optimization (most common cause)

Chinese and many other OEM ROMs add aggressive battery savers that kill
background processes and suspend their job queues. The device behaves as if
WorkManager does not work, even though the tasks are correctly scheduled.

The canonical, per-vendor step-by-step whitelist instructions live at
[**dontkillmyapp.com**](https://dontkillmyapp.com). Whitelist your app from
battery optimization and enable auto-start where the ROM requires it:

| OEM / ROM | Guide | Minimum you usually need |
| --- | --- | --- |
| Xiaomi / MIUI | [dontkillmyapp.com/xiaomi](https://dontkillmyapp.com/xiaomi) | Battery → no restrictions; Autostart enabled; lock app in Recents |
| Huawei / EMUI / HarmonyOS | [dontkillmyapp.com/huawei](https://dontkillmyapp.com/huawei) | App launch → Manage manually → allow background activity |
| OPPO / ColorOS | [dontkillmyapp.com/oppo](https://dontkillmyapp.com/oppo) | Allow auto-launch + background activity; no battery optimization |
| OnePlus / OxygenOS | [dontkillmyapp.com/oneplus](https://dontkillmyapp.com/oneplus) | Battery optimization → Don't optimize; disable "Optimize battery usage" |
| Samsung / One UI | [dontkillmyapp.com/samsung](https://dontkillmyapp.com/samsung) | App → Battery → Unrestricted; disable "Put app to sleep" |
| Vivo / Funtouch OS | [dontkillmyapp.com/vivo](https://dontkillmyapp.com/vivo) | Autostart enabled; Background activity allowed |
| Realme / ColorOS-based | [dontkillmyapp.com/realme](https://dontkillmyapp.com/realme) | Allow auto-launch; no battery optimization |
| Tecno / Infinix / XOS | [dontkillmyapp.com/tecno](https://dontkillmyapp.com/tecno) | Allow background running; disable "Auto power saving" |
| Sony | [dontkillmyapp.com/sony](https://dontkillmyapp.com/sony) | Battery → App power management → no optimization |
| Lenovo / Motorola | [dontkillmyapp.com/lenovo](https://dontkillmyapp.com/lenovo) · [motorola](https://dontkillmyapp.com/motorola) | Disable background restriction / adaptive battery for the app |
| Asus | [dontkillmyapp.com/asus](https://dontkillmyapp.com/asus) | Auto-start manager → allow |
| Meizu | [dontkillmyapp.com/meizu](https://dontkillmyapp.com/meizu) | Allow background running |

<Info>
Some ROMs still suspend periodic work even after whitelisting (a known
Blackview/stock-Android-variant behavior, for example). On those devices the
only reliable workaround is a "lock app" feature that prevents the process from
being killed. If you find a device where *no* combination of settings makes
deferred work run, note it in the issue with `adb logcat` + device details.
</Info>

## Android: expedited work (available now)

For **one-off tasks that must start promptly** (e.g. a user-initiated upload),
register the task as *expedited* by passing
[`OutOfQuotaPolicy`](https://pub.dev/documentation/workmanager/latest/workmanager/OutOfQuotaPolicy.html):

```dart
await Workmanager().registerOneOffTask(
  'sync.user_data',
  'syncTask',
  inputData: {'source': 'user'},
  outOfQuotaPolicy: OutOfQuotaPolicy.runAsNonExpeditedWorkRequest,
);
```

Expedited work uses a high-priority job (and on API 31+ a foreground service
managed by WorkManager) that is far less affected by battery restrictions. Two
important rules:

- Expedited jobs **cannot** use battery, charging, or device-idle constraints.
- They are intended for short, user-visible work, not long-running processing.

For genuinely **long-running** work (minutes of active processing), the
recommended solution is the plugin's foreground-service support (shipped in
the 0.10.0 line, [PR #698](https://github.com/fluttercommunity/flutter_workmanager/pull/698)):
pass a `foregroundServiceConfig` to `registerOneOffTask` or
`registerPeriodicTask`. The worker is promoted to a foreground service as soon
as it starts and shows a persistent notification for the whole duration of the
task, so the OS will not kill it while it runs. See
[Quick Start → Long-running tasks (foreground service)](quickstart#long-running-tasks-foreground-service)
for the config shape and Android 14+ service-type requirements.

## Android: constraint gotchas

Tasks are **deferred until every constraint is met** - and "met" is checked at
the OS's discretion, not continuously:

- `networkType` requiring connectivity is the most common silent blocker: if
  the device is offline (or the network does not match the requested type) at
  execution time, the task simply waits. WorkManager only receives network
  change callbacks, so a missing network at the exact scheduling moment defers
  execution.
- `requiresCharging` / `requiresBatteryNotLow` delay work until the device is
  on power / battery is healthy.
- `requiresDeviceIdle` means the task only runs in Doze mode - often
  effectively never on ROMs with aggressive idle management.
- Doze (Android 6+) and App Standby throttle deferred work to maintenance
  windows when the device is stationary and unused. Expect **± minutes to
  hours** of fluctuation versus the theoretical period.
- Android enforces a 15-minute minimum period for periodic tasks.

See [Task Customization → Constraints](customization#task-constraints) for the
API details and platform differences.

## Verifying with adb

Confirm the task is actually scheduled and see *why* it is being deferred:

```bash
# Are the jobs scheduled at all?
adb shell dumpsys jobscheduler | grep yourapp

# Detailed job state (constraints pending, stopped, etc.)
adb shell dumpsys jobscheduler yourapp

# Is the app exempt from battery optimization / Doze?
adb shell dumpsys deviceidle whitelist

# Watch scheduling decisions live
adb logcat -s JobScheduler WorkManager
```

For a debug-only force run:

```bash
adb shell cmd jobscheduler run -f yourapp JOB_ID
```

A task that appears in `dumpsys jobscheduler` with `CONSTRAINT_BATTERY_NOT_LOW`
or `CONSTRAINT_CONNECTIVITY` pending is not broken - its constraints are not
met yet. See the [Debugging guide](debugging) for more diagnostics.

## iOS: terminated apps do not run

On iOS, when the user swipes the app away (or the system terminates it),
**no background work runs until the app is launched again**. This is an OS
policy, not a plugin limitation:

- `BGAppRefreshTask` / `BGProcessingTask` / `BGHealthResearchTask` are only
  delivered when iOS decides to relaunch your app for them.
- `BGProcessingTask` additionally requires the device to be **idle** (and
  optionally charging / on network).
- "Works while app is in background, stops after close" is expected behavior.

Make sure the basics are right before debugging further:

- The identifier is listed in `BGTaskSchedulerPermittedIdentifiers` in
  `Info.plist` and `UIBackgroundModes` includes `fetch` / `processing`.
- Launch handlers are registered before app launch finishes
  (`WorkmanagerPlugin.registerLaunchHandlers()` in `AppDelegate` - see the
  [Quick Start](quickstart) UIScene setup).
- Prefer processing tasks for work that needs minutes; one-off and refresh
  tasks get only seconds of budget.

## Reporting a genuine bug

If you believe the plugin itself is broken, the issue must include:

1. Fresh install, battery optimization **disabled**, whitelisted, on a current
   plugin version.
2. The task registered once, the app closed, and a full closed-state cycle.
3. Proof from the device: `adb logcat` output or iOS device logs showing the
   task never fired (or the exact failure).
4. Device model + OS version.

Without that evidence, issues almost always turn out to be OEM battery
management or OS scheduling policy - and this page is the canonical reference
for those.
