A: Yes! Tasks are registered with the OS (Android WorkManager / iOS BGTaskScheduler), not your Flutter app. They survive:
- App force-close
- Phone reboot
- App uninstall → reinstall (if task IDs are consistent)
A: It depends on the worker type:
| Worker Type | Memory Usage | Startup Time |
|---|---|---|
| Native Workers | 2-5 MB | <100ms |
| Dart Workers | ~50 MB | 200-500ms |
| Custom Native Workers | Varies (typically 1-10 MB) | <100ms |
Why the difference?
- Native workers execute without starting Flutter engine
- Dart workers need full Flutter engine initialization
A: Technically yes, but not recommended for several reasons:
iOS Limitation:
- Each task in chain must complete within 30 seconds
- iOS may cancel long chains
- Recommendation: Keep chains to 3-5 tasks max on iOS
Android:
- No strict limit, but very long chains can be fragile
- Recommendation: Keep chains to 5-10 tasks max
Better approach:
// Instead of: Task1 → Task2 → ... → Task100
// Use: Periodic task that processes batches
NativeWorkManager.enqueue(
taskId: 'batch-processor',
trigger: TaskTrigger.periodic(Duration(hours: 1)),
worker: DartWorker(callbackId: 'processBatch'),
);A: The chain stops at the failed task:
- Tasks before failure: ✅ Completed successfully
- Failed task: ❌ Marked as failed
- Tasks after failure: ⏸️ Not executed (cancelled)
Example:
TaskA (✅) → TaskB (❌ FAILS) → TaskC (⏸️ Skipped) → TaskD (⏸️ Skipped)
Retry behavior:
- If you configured retry policy, the failed task retries
- Chain continues only if retry succeeds
- If all retries fail, chain stops permanently
A: ~90% API compatible with minor syntax changes required.
Main differences:
- Import:
import 'package:native_workmanager/native_workmanager.dart'; - Initialization:
NativeWorkManager.initialize()vsWorkmanager.initialize() - Enqueue syntax: Different trigger API
- Native workers: New capability not in workmanager
A: No, background tasks are for periodic work, not continuous tracking.
Why?
- Tasks run at intervals (minimum 15 minutes on iOS, 15-30 minutes on Android)
- Tasks have execution time limits (30 seconds on iOS, 10 minutes on Android)
- OS may defer tasks to save battery
For location tracking, use:
geolocatorwith background modesbackground_location- Foreground service on Android
Use native_workmanager for:
- Upload location batches every hour
- Process and sync location logs
- Periodic geofence checks
A: It depends on constraints:
Android Doze Mode:
- Tasks are deferred during Doze mode by default
- Use constraints to wait for appropriate conditions:
constraints: Constraints(
requiresNetwork: true, // Wait for network
requiresCharging: true, // Wait for charging
requiresBatteryNotLow: true, // Wait until battery is OK
)iOS Low Power Mode:
- Background tasks have lower priority
- May be delayed or skipped
- Use
requiresCharging: truefor critical tasks
A: No, native_workmanager is for flexible background tasks, not exact alarms.
Why?
- iOS doesn't support exact-time background tasks
- Android Doze mode defers tasks anyway
- Background tasks are designed for flexibility
For exact alarms, use:
flutter_local_notificationsandroid_alarm_manager_plus(Android only)- Platform channels to native alarm APIs
Use native_workmanager for:
- Periodic work that can be flexible (±15 minutes is OK)
- Background data sync
- File processing tasks
A: Follow these strategies:
1. Use logging:
worker: DartWorker(
callbackId: 'myTask',
onProgress: (progress) {
print('Task progress: $progress'); // Won't show in release
// Use proper logging instead:
developer.log('Task progress: $progress', name: 'NativeWorkManager');
},
)2. Listen to task events:
NativeWorkManager.events.listen((event) {
print('Task ${event.taskId}: ${event.success ? "✅" : "❌"}');
print('Message: ${event.message}');
});3. Check native logs:
iOS: Use Xcode Console while device is connected
Android: Use adb logcat or Android Studio Logcat
4. Test in foreground first:
// Test task logic in foreground before background
await myTaskLogic(); // Test this works
// Then schedule as background taskA: Direct data passing between tasks is not natively supported. Use shared storage as a workaround:
// Task 1: Save result
await NativeWorkManager.beginWith(
TaskRequest(id: 'task1', worker: DartWorker(callbackId: 'saveData')),
).then(
TaskRequest(id: 'task2', worker: DartWorker(callbackId: 'useData')),
).enqueue();
// In task1 callback:
void saveData() async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString('task1_result', jsonEncode(result));
}
// In task2 callback:
void useData() async {
final prefs = await SharedPreferences.getInstance();
final data = jsonDecode(prefs.getString('task1_result')!);
// Use data...
}A: Platform-specific minimums:
| Platform | Minimum Interval | Notes |
|---|---|---|
| Android | 15 minutes | WorkManager API limitation |
| iOS | 15 minutes | BGTaskScheduler limitation |
Example:
// ✅ Works (1 hour)
trigger: TaskTrigger.periodic(Duration(hours: 1))
// ⚠️ Will be clamped to 15 minutes
trigger: TaskTrigger.periodic(Duration(minutes: 5))
// ❌ Will fail
trigger: TaskTrigger.periodic(Duration(seconds: 30))A: Only if your tasks use network:
Android (android/app/src/main/AndroidManifest.xml):
<uses-permission android:name="android.permission.INTERNET" />iOS (ios/Runner/Info.plist):
- Network access allowed by default
- If using HTTP (not HTTPS), configure App Transport Security
Permissions for workers:
- HTTP workers: Need INTERNET permission
- File workers: No special permissions
- Crypto workers: No special permissions
A: Yes, but avoid conflicts:
Compatible:
- ✅
flutter_local_notifications- Different use case (notifications vs tasks) - ✅
geolocator- Can coexist (use geolocator for continuous, native_workmanager for periodic) - ✅
shared_preferences- For task data storage
Potential conflicts:
⚠️ workmanager- Same underlying APIs, choose one⚠️ workmanager- Same underlying APIs, choose one
Best practice: Use native_workmanager as your primary background task solution.
A: Use retry policies and constraints:
await NativeWorkManager.enqueue(
taskId: 'critical-sync',
trigger: TaskTrigger.oneTime(),
worker: NativeWorker.httpSync(url: 'https://api.example.com/sync'),
constraints: Constraints(
requiresNetwork: true,
backoffPolicy: BackoffPolicy.exponential, // Exponential backoff
backoffDelayMs: 30000, // Start with 30s delay
maxAttempts: 5, // Retry up to 5 times
),
);Retry strategies:
BackoffPolicy.linear: Fixed delay (30s, 30s, 30s, ...)BackoffPolicy.exponential: Growing delay (30s, 60s, 120s, 240s, ...)
Support channels:
- 💬 GitHub Discussions - Ask questions
- 🐛 Issue Tracker - Report bugs
- 📖 Documentation - Comprehensive guides
- 📧 Email: support@brewkits.dev - Direct support
Before asking:
- Check this FAQ
- Read Getting Started Guide
- Review Use Cases for similar scenarios
- Search existing issues
Common reasons:
-
Task not triggered yet
- iOS defers background tasks
- Test by backgrounding app, waiting 30+ seconds
-
30-second limit exceeded
- Tasks must complete in 30 seconds
- Use native workers (faster startup, no engine overhead)
- Split into chains
-
Low Power Mode active
- iOS deprioritizes background tasks
- Add
requiresCharging: trueconstraint
-
BGTaskScheduler not configured
- Check
Info.plisthasBGTaskSchedulerPermittedIdentifiers - See iOS Guide
- Check
Common reasons:
-
Minimum SDK version too low
- Plugin requires API 26+ (Android 8.0+)
- Edit
android/app/build.gradle:
defaultConfig { minSdk 26 // Must be 26 or higher! }
-
Initialization not called or not awaited
- Ensure
await NativeWorkManager.initialize()inmain()
void main() async { WidgetsFlutterBinding.ensureInitialized(); await NativeWorkManager.initialize(); // ← Must await! runApp(MyApp()); }
- Ensure
-
Build cache corruption
- Clean and rebuild:
flutter clean rm -rf android/build android/app/build flutter pub get flutter build apk --debug
-
Check logcat for details
adb logcat -s NativeWorkmanagerPlugin
See also: Full Android Setup Guide
Common reasons:
-
Doze Mode
- Android defers tasks in Doze
- Use
requiresCharging: trueor wait for idle window
-
Battery Saver Mode
- Tasks have lower priority
- Use
requiresBatteryNotLow: true
-
Network constraint not met
- Task waits for network
- Check
requiresNetwork: trueconstraint
-
Minimum interval not met
- Periodic tasks minimum: 15 minutes
- Check your trigger interval
A: Yes! See Custom Native Workers Guide
Quick example:
Kotlin:
class MyCustomWorker : AndroidWorker {
override suspend fun doWork(input: String?): WorkerResult {
// Your Kotlin code here
return WorkerResult.success("Done!")
}
}Swift:
class MyCustomWorker: IosWorker {
func doWork(input: String?) async throws -> WorkerResult {
// Your Swift code here
return WorkerResult.success(data: "Done!")
}
}A: Minimal impact:
Initialization:
- Native platform APIs (WorkManager, BGTaskScheduler)
- Time: <10ms on modern devices
- Memory: <1MB
Background task execution:
- No impact on app foreground performance
- Tasks run in separate process/thread
A: Yes! Production-ready features:
- ✅ Security audited - No critical vulnerabilities
- ✅ 462 tests passing - 100% pass rate
- ✅ Used in production - Apps with 1M+ users
- ✅ MIT licensed - Commercial use allowed
- ✅ Comprehensive docs - 20+ guides
Didn't find your question?