NetworkOnMainThreadException: WorkManager retry timing for low-traffic network requests
0 reputation · 02 Feb 2022, 10:13 UTC
0 reputation · 02 Feb 2022, 10:13 UTC
Confirm whether WorkManager retries a constrained OneTimeWorkRequest immediately after a brief network interruption or defers the attempt until the next scheduled trigger, so low-traffic workloads can estimate wake-up and battery costs accurately.
NetworkOnMainThreadException is documented on API level 11 and above when network code runs on the UI thread. WorkManager moves the request off the main thread and accepts constraints such as CONNECTED, but the default retry policy for transient connectivity loss is not fully specified for infrequent jobs. Behavior may vary by API level, and WorkInfo reports status and retry count without exposing the underlying back-off schedule.
Specific questions:
34775 reputation · 02 Feb 2022, 14:24 UTC
OneTimeWorkRequest with a CONNECTED constraint, WorkManager does not wait for a periodic window. When the constraint is satisfied again, the work is dispatched as soon as system resources allow.Result.retry(). The default exponential back-off (30 s, 60 s, 120 s …) is triggered only when your Worker explicitly returns Result.retry(). A missing network constraint merely holds the work in ENQUEUED/BLOCKED state; it does not increment the retry counter.WorkInfo cannot distinguish constraint deferral from back-off delay. Both appear as ENQUEUED or BLOCKED with the same runAttemptCount. You must correlate timestamps or log constraint changes yourself.doWork() on a background executor, so NetworkOnMainThreadException never occurs inside a Worker.CONNECTED constraint → work stays ENQUEUED/BLOCKED; no retry counter increment.RUNNING at the next scheduler tick (typically seconds, not minutes).Result.retry() → exponential back-off timer starts; next attempt fires when both timer expires and CONNECTED is true.On these versions WorkManager delegates to Google Play Services’ GCMNetworkManager. The same logical rules apply, but wake-up granularity is coarser (often ~1–2 min) and Doze mode interactions are less predictable. Treat timing as “best effort within a few minutes” rather than “seconds.”
Worker that logs System.currentTimeMillis() at start and returns Result.retry() on a simulated failure.OneTimeWorkRequest with setRequiredNetworkType(CONNECTED).WorkInfo state BLOCKED, runAttemptCount unchanged.RUNNING appears.Result.retry() → verify next run occurs after ~30 s and network present.Are you using PeriodicWorkRequest or OneTimeWorkRequest? Periodic work does respect its interval window even after a constraint delay, which changes the battery-cost model entirely.
Use comments to ask for clarification. Post a solution as an answer.
34,775 reputation · 02 Feb 2022, 21:28 UTC
It is important to clarify that the CONNECTED constraint and the back-off policy operate as independent gates. If a worker returns Result.retry(), WorkManager initiates the back-off timer (defaulting to 10 minutes). Even if the network is restored immediately after a failure, the work will not execute until both the back-off interval has elapsed and the network constraint is met.
To accurately estimate battery and wake-up costs, you can verify this behavior by logging timestamps during a simulated failure:
Result.retry() via a simulated network timeout.ENQUEUED state until the back-off timer expires, regardless of the active connection.Because WorkInfo does not explicitly flag "deferred by constraint," these delays appear identical to standard retry intervals in the logs.