Mobile

Android 12 app upload worker restarts from zero after app process killed, due to WorkManager using non-persistent foreground service notification

Environment

Environment

App built with React Native (0.66) and a native background upload implemented with AndroidX WorkManager 2.7 on Android 12 (Pixel 5). Uploads are large (100+ MB). Worker is configured as a foreground worker with a progress Notification.

Symptoms

Symptoms

When the user switches to another app or the system kills the RN JS process under memory pressure, large background uploads restart from 0% on next launch; partial progress isn't resumed. Logs show the previous Work continuation failing with 'Interrupted' and a new WorkRequest starting with fresh input data.

Observations

Observations

WorkManager shows one-time work with unique name and ExistingWorkPolicy.REPLACE. The Worker creates a foreground notification via setForegroundAsync with NotificationCompat.Builder using the app's channel. The upload code writes to a temp file and streams to server in chunks, reporting progress via setForegroundAsync. When process is killed (system OOM), the Worker is restarted by WorkManager but the original temporary file was stored in app-cache (getCacheDir()) which may have been cleared by the system before restart. Additionally, the WorkRequest inputData includes the upload URL and file path; the file path pointed to cache/temporary file. Because policy is REPLACE and WorkManager recreates the job on restart, the partial bytes are lost.

Already attempted

Already attempted

Switched ExistingWorkPolicy to KEEP to prevent duplicate restarts — observed WorkManager still restarted a new Worker because the previous run was marked failed when process was killed. Moved temporary file to external storage (getExternalFilesDir) to survive process kill — uploads resumed when Worker restarted, but Android killed app more aggressively and the notification disappeared. Tried using ForegroundService directly — more complex and still suffered from cache cleanup.

Question

Question

How can I implement robust resumable uploads that survive app process kills and restart by the system, using WorkManager/foreground services in Android 12, without requiring the user to manually restart uploads?

COMMUNITY RESPONSES

Verified community troubleshooting

0 replies

No answers yet..

Showing 0 of 0 community responses
AI DIAGNOSTICS

Incident analysis

Updated 1w ago• Trouble ID

Most likely causes

Partial upload state was stored in app cache (volatile) which the system may purge when killing the process, preventing resumption. 95%
WorkManager's ExistingWorkPolicy.REPLACE or ambiguous unique naming causes new work to start instead of resuming previous run. 80%
Foreground notification not correctly tied to a persistent foreground service, leading the OS to deprioritize the process and kill it under memory pressure. 60%

Summary

The core issues are: (1) using app-internal cache for partial upload state which the OS may reclaim on process kill, and (2) treating WorkManager inputData/one-time work in a way that replaces lost runs instead of resuming. WorkManager will attempt to restart interrupted work, but if the worker's state (temp file, local offsets) was stored in volatile cache or in-memory, the resumed worker has no state to continue from. The foreground notification and WorkManager policy alone don't guarantee persistence of intermediate upload state across process restarts. A resumable upload requires persistent state (on-disk) and an idempotent protocol on the server or support for byte-range/resumable APIs.

Suggested Fixes

Diagnostic step 1
Use a durable storage location for partial upload state: write progress metadata (upload ID, byte offset, temp file path) to a database (Room) or to files in getExternalFilesDir so they survive process kill and are not auto-pruned by the system.
Diagnostic step 2
Implement or use a resumable upload protocol (e.g., tus.io, HTTP range uploads, or server-provided upload-id and offset) so the client can query server for current offset and resume from where it left off.
Diagnostic step 3
Configure WorkManager to use unique work with ExistingWorkPolicy.KEEP and design your worker to detect an existing incomplete upload by reading persistent metadata; on launch, the worker should query server for upload offset and resume streaming from that offset.

Continue troubleshooting

Matched from the title, description and tags