How do you handle background work and threading in Android?
The main thread draws the UI. Blocking it for more than a few hundred milliseconds causes jank; blocking it for five seconds causes an ANR. Network calls, database queries, and file I/O must never run there.
Coroutines are the modern answer:
viewModelScopeties work to the ViewModel and cancels it automatically when the ViewModel clears.lifecycleScopeties work to an Activity or Fragment lifecycle.- Dispatchers choose the thread pool —
Dispatchers.IOfor network and disk,Dispatchers.Defaultfor CPU-bound work,Dispatchers.Mainfor UI.withContextswitches between them cleanly. - Structured concurrency means cancelling a scope cancels its children, which prevents leaked work.
For deferrable, guaranteed work — WorkManager. This is the important distinction. Work that must complete even if the app is closed or the device restarts — uploading a file, periodic sync, sending analytics — belongs in WorkManager, which handles constraints (network available, charging), retries with backoff, and chaining. It respects Doze and battery optimisation rather than fighting them.
What not to use: AsyncTask is deprecated and leaks Activities; raw Thread gives no lifecycle awareness; and a plain background Service is unreliable under background execution limits since Android 8.
Note: Manufacturer battery optimisation aggressively kills background work on some devices. Mentioning it — and that you would use WorkManager and expedited work rather than assuming a Service stays alive — signals real experience.





