Skip to content

Commit d34763d

Browse files
authored
fix: prevent NullPointerException in BackgroundWorker.getDartTask (#636)
* chore(release): publish packages - workmanager_apple@0.9.1 - workmanager@0.9.0+1 * docs: fix incorrect UIBackgroundModes documentation - Remove invalid 'processing' value from UIBackgroundModes - Add clarification that BGTaskScheduler doesn't require UIBackgroundModes - Link to Apple's official UIBackgroundModes documentation - Update workmanager version to 0.9.0 in installation instructions Fixes #633 * Revert "docs: fix incorrect UIBackgroundModes documentation" This reverts commit 7116f5f. * docs: improve iOS background modes documentation links - Replace Xcode Help link with Apple's Configuration Guide - Add link to UIBackgroundModes property list documentation - Provide both practical configuration and technical reference links Fixes #633 * fix: prevent NullPointerException in BackgroundWorker.getDartTask - Remove non-null assertion operator (!!) from dartTask property - Add null checks in all methods that use dartTask - Handle null dart task gracefully with proper error reporting - Fixes crash when DART_TASK_KEY is missing from worker input data Fixes #635 * Revert "chore(release): publish packages" This reverts commit aa9e3b6.
1 parent e2e1d54 commit d34763d

File tree

4 files changed

+52
-7
lines changed

4 files changed

+52
-7
lines changed

docs/quickstart.mdx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ iOS requires a 5-minute setup in Xcode. Choose your approach based on your needs
2828
#### Option A: Periodic Tasks (Recommended for most use cases)
2929
For regular data sync, notifications, cleanup - uses iOS Background Fetch:
3030

31-
1. **Enable Background Modes** in Xcode target capabilities ([Xcode Help](https://help.apple.com/xcode/mac/current/#/devbfa1532c4)) and add to Info.plist:
31+
1. **Enable Background Modes** in Xcode target capabilities ([Configuration Guide](https://developer.apple.com/documentation/xcode/configuring-background-execution-modes)) and add to Info.plist ([UIBackgroundModes reference](https://developer.apple.com/documentation/bundleresources/information-property-list/uibackgroundmodes)):
3232
```xml
3333
<key>UIBackgroundModes</key>
3434
<array>
@@ -45,7 +45,7 @@ For regular data sync, notifications, cleanup - uses iOS Background Fetch:
4545
#### Option B: Processing Tasks (For complex operations)
4646
For file uploads, data processing, longer tasks - uses BGTaskScheduler:
4747

48-
1. **Enable Background Modes** in Xcode target capabilities ([Xcode Help](https://help.apple.com/xcode/mac/current/#/devbfa1532c4)) and add to Info.plist:
48+
1. **Enable Background Modes** in Xcode target capabilities ([Configuration Guide](https://developer.apple.com/documentation/xcode/configuring-background-execution-modes)) and add to Info.plist ([UIBackgroundModes reference](https://developer.apple.com/documentation/bundleresources/information-property-list/uibackgroundmodes)):
4949
```xml
5050
<key>UIBackgroundModes</key>
5151
<array>
@@ -75,7 +75,7 @@ WorkmanagerPlugin.registerBGProcessingTask(
7575
#### Option C: Periodic Tasks with Custom Frequency
7676
For periodic tasks with more control than Background Fetch - uses BGTaskScheduler with frequency:
7777

78-
1. **Enable Background Modes** in Xcode target capabilities ([Xcode Help](https://help.apple.com/xcode/mac/current/#/devbfa1532c4)) and add to Info.plist:
78+
1. **Enable Background Modes** in Xcode target capabilities ([Configuration Guide](https://developer.apple.com/documentation/xcode/configuring-background-execution-modes)) and add to Info.plist ([UIBackgroundModes reference](https://developer.apple.com/documentation/bundleresources/information-property-list/uibackgroundmodes)):
7979
```xml
8080
<key>UIBackgroundModes</key>
8181
<array>

example/ios/Podfile.lock

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,46 @@
11
PODS:
22
- Flutter (1.0.0)
3+
- integration_test (0.0.1):
4+
- Flutter
35
- path_provider_foundation (0.0.1):
46
- Flutter
57
- FlutterMacOS
68
- permission_handler_apple (9.3.0):
79
- Flutter
10+
- shared_preferences_foundation (0.0.1):
11+
- Flutter
12+
- FlutterMacOS
813
- workmanager_apple (0.0.1):
914
- Flutter
1015

1116
DEPENDENCIES:
1217
- Flutter (from `Flutter`)
18+
- integration_test (from `.symlinks/plugins/integration_test/ios`)
1319
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
1420
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
21+
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
1522
- workmanager_apple (from `.symlinks/plugins/workmanager_apple/ios`)
1623

1724
EXTERNAL SOURCES:
1825
Flutter:
1926
:path: Flutter
27+
integration_test:
28+
:path: ".symlinks/plugins/integration_test/ios"
2029
path_provider_foundation:
2130
:path: ".symlinks/plugins/path_provider_foundation/darwin"
2231
permission_handler_apple:
2332
:path: ".symlinks/plugins/permission_handler_apple/ios"
33+
shared_preferences_foundation:
34+
:path: ".symlinks/plugins/shared_preferences_foundation/darwin"
2435
workmanager_apple:
2536
:path: ".symlinks/plugins/workmanager_apple/ios"
2637

2738
SPEC CHECKSUMS:
2839
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
40+
integration_test: 4a889634ef21a45d28d50d622cf412dc6d9f586e
2941
path_provider_foundation: 608fcb11be570ce83519b076ab6a1fffe2474f05
3042
permission_handler_apple: 4ed2196e43d0651e8ff7ca3483a069d469701f2d
43+
shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
3144
workmanager_apple: 904529ae31e97fc5be632cf628507652294a0778
3245

3346
PODFILE CHECKSUM: 1959d098c91d8a792531a723c4a9d7e9f6a01e38

example/ios/Runner.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,12 +369,16 @@
369369
);
370370
inputPaths = (
371371
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
372+
"${BUILT_PRODUCTS_DIR}/integration_test/integration_test.framework",
372373
"${BUILT_PRODUCTS_DIR}/path_provider_foundation/path_provider_foundation.framework",
374+
"${BUILT_PRODUCTS_DIR}/shared_preferences_foundation/shared_preferences_foundation.framework",
373375
"${BUILT_PRODUCTS_DIR}/workmanager_apple/workmanager_apple.framework",
374376
);
375377
name = "[CP] Embed Pods Frameworks";
376378
outputPaths = (
379+
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/integration_test.framework",
377380
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider_foundation.framework",
381+
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/shared_preferences_foundation.framework",
378382
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/workmanager_apple.framework",
379383
);
380384
runOnlyForDeploymentPostprocessing = 0;

workmanager_android/android/src/main/kotlin/dev/fluttercommunity/workmanager/BackgroundWorker.kt

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class BackgroundWorker(
4646
}
4747

4848
private val dartTask
49-
get() = workerParams.inputData.getString(DART_TASK_KEY)!!
49+
get() = workerParams.inputData.getString(DART_TASK_KEY)
5050

5151
private val runAttemptCount = workerParams.runAttemptCount
5252
private val randomThreadIdentifier = Random().nextInt()
@@ -86,11 +86,20 @@ class BackgroundWorker(
8686
return@ensureInitializationCompleteAsync
8787
}
8888

89+
val localDartTask = dartTask
90+
91+
if (localDartTask == null) {
92+
val exception = IllegalStateException("Dart task is null")
93+
WorkmanagerDebug.onExceptionEncountered(applicationContext, null, exception)
94+
completer?.set(Result.failure())
95+
return@ensureInitializationCompleteAsync
96+
}
97+
8998
val dartBundlePath = flutterLoader.findAppBundlePath()
9099

91100
val taskInfo =
92101
TaskDebugInfo(
93-
taskName = dartTask,
102+
taskName = localDartTask,
94103
inputData = payload,
95104
startTime = startTime,
96105
callbackHandle = callbackHandle,
@@ -132,9 +141,18 @@ class BackgroundWorker(
132141
) {
133142
val fetchDuration = System.currentTimeMillis() - startTime
134143

144+
val localDartTask = dartTask
145+
146+
if (localDartTask == null) {
147+
val exception = IllegalStateException("Dart task is null")
148+
WorkmanagerDebug.onExceptionEncountered(applicationContext, null, exception)
149+
completer?.set(Result.failure())
150+
return
151+
}
152+
135153
val taskInfo =
136154
TaskDebugInfo(
137-
taskName = dartTask,
155+
taskName = localDartTask,
138156
inputData = payload,
139157
startTime = startTime,
140158
)
@@ -175,7 +193,17 @@ class BackgroundWorker(
175193
// Convert payload to the format expected by Pigeon (Map<String?, Object?>)
176194
val pigeonPayload = payload.mapKeys { it.key as String? }.mapValues { it.value as Object? }
177195

178-
flutterApi.executeTask(dartTask, pigeonPayload) { result ->
196+
val localDartTask = dartTask
197+
198+
if (localDartTask == null) {
199+
val exception = IllegalStateException("Dart task is null")
200+
WorkmanagerDebug.onExceptionEncountered(applicationContext, null, exception)
201+
202+
stopEngine(Result.failure(), exception.message)
203+
return
204+
}
205+
206+
flutterApi.executeTask(localDartTask, pigeonPayload) { result ->
179207
when {
180208
result.isSuccess -> {
181209
val wasSuccessful = result.getOrNull() ?: false

0 commit comments

Comments
 (0)