Background Work (Services, WorkManager, Foreground Services & Scheduling)
Schedule and execute background operations efficiently with Services, Foreground Services, and WorkManager API.
Module 15: Background Work (Services, WorkManager, Foreground Services & Scheduling)
Learning Objectives
By the end of this module, you’ll understand:
- Android process lifecycle
- Foreground vs background execution
- Process importance hierarchy
- Background execution limits
- Services
- Started Services
- Bound Services
- Foreground Services
- Broadcast Receivers
- AlarmManager
- JobScheduler
- WorkManager
- Constraints
- Periodic work
- Chaining work
- Retry strategies
- Battery optimizations
- Choosing the correct background API
Part 1 — Android Owns Your Process
One of the biggest mindset shifts.
On desktop:
Program Starts
↓
Runs Forever
↓
User Closes It
Android?
App Starts
↓
User Leaves
↓
OS May Kill Process
↓
Later Restart It
Your application does not own its lifetime.
Android does.
This is fundamental.
Why?
Imagine:
100 apps running simultaneously.
If Android never stopped background apps:
RAM
↓
Full
↓
Phone Slows
↓
Battery Dies
Instead Android aggressively manages resources.
Part 2 — Process Importance
Android assigns every process a priority.
Conceptually:
Foreground Process
│
Visible Process
│
Service Process
│
Cached Process
The lower the importance:
The more likely Android kills it.
Foreground Process
Highest priority.
Examples:
- Current Activity
- Foreground Service
- Music player with notification
- Active phone call
Very unlikely to be killed.
Visible Process
User can still see it.
Example:
Dialog Activity behind another transparent Activity.
Still important.
Service Process
Running background service.
Medium priority.
Cached Process
Nothing visible.
Nothing active.
Android may terminate it at any time.
Part 3 — Background Execution Limits
Android 8 (Oreo) introduced major restrictions.
Before Android 8:
Apps could run background services almost indefinitely.
Problem:
200 Apps
↓
Background Services
↓
Battery Dead
Android fixed this by heavily limiting background execution.
Today:
Apps must justify long-running work.
Part 4 — Types of Background Work
Not every task is the same.
Imagine:
Upload Photo
↓
Sync Database
↓
Play Music
↓
Download File
↓
Daily Backup
Each requires a different API.
This is why Android has several background execution mechanisms.
Part 5 — Services
A Service is a component designed to perform work without a UI.
Important misconception:
A Service is not a separate thread.
It runs on the app’s main thread unless you explicitly move work elsewhere (for example, using coroutines).
Service:
No UI
↓
Background Work
Started Service
Flow:
Activity
↓
Start Service
↓
Runs
↓
Stops Itself
Suitable for work that begins because the app requests it.
Historically used more often.
Today, many long-running jobs are better handled by WorkManager or Foreground Services.
Bound Service
Suppose:
Music app.
Activity
↓
Bind
↓
Music Service
The Activity communicates with the Service.
When every client unbinds:
The Service can stop.
Useful for ongoing interaction between components.
Part 6 — Foreground Services
Suppose:
Navigation.
Google Maps
↓
Navigation
↓
Screen Off
Should navigation stop?
No.
Android allows long-running work if:
The user is clearly informed.
Requirement:
Persistent notification.
Example:
Navigation Running
↓
Notification Visible
This tells the user:
“This app is actively doing something important.”
Common Foreground Service examples:
- Music playback
- GPS navigation
- Fitness tracking
- Active voice recording
- Ongoing phone calls
- File uploads/downloads that the user expects to continue
Foreground Service Types
Modern Android requires declaring the purpose of many foreground services.
Examples:
Location
Media Playback
Camera
Microphone
Data Sync
This improves transparency and security.
Part 7 — Broadcast Receivers
Imagine:
Phone finishes booting.
Battery becomes low.
Airplane mode changes.
Wi-Fi connects.
These are system events.
Broadcast Receivers listen for them.
Flow:
System Event
↓
Broadcast
↓
Receiver
↓
Your Code
Examples:
- Device boot completed
- Battery status changed
- Network connectivity changes (subject to modern restrictions)
- Time zone changed
- Locale changed
Modern Android limits many implicit broadcasts to reduce unnecessary wake-ups.
Part 8 — AlarmManager
Need something to happen at a specific time?
Example:
8:00 AM
↓
Show Reminder
AlarmManager schedules time-based work.
However:
It’s not intended for complex background processing.
It’s primarily about when something should happen.
Examples:
- Alarm clock
- Calendar reminder
- Medication reminder
Exact vs Inexact Alarms
Exact:
8:00:00 AM
Inexact:
Around 8:00 AM
Android prefers inexact alarms because they allow batching, which saves battery.
Recent Android versions restrict exact alarms unless the app qualifies or has special permission.
Part 9 — JobScheduler
Android introduced JobScheduler to batch work efficiently.
Instead of:
App A
↓
Wake CPU
then
App B
↓
Wake CPU
Android groups jobs:
Wake CPU Once
↓
Run Multiple Jobs
Battery savings.
JobScheduler was the foundation for more modern APIs.
Part 10 — WorkManager
Google’s recommended solution for most deferrable background work.
Rule of thumb:
If your task:
- Must eventually run
- Doesn’t need immediate execution
- Should survive app restarts
Use WorkManager.
Architecture:
App
↓
WorkManager
↓
JobScheduler / AlarmManager
↓
System
WorkManager chooses the best underlying scheduler depending on Android version and device conditions.
One-Time Work
Example:
Upload Image
Runs once.
Then finishes.
Periodic Work
Example:
Sync Every 24 Hours
Repeats according to WorkManager’s constraints and scheduling policies (not at an exact clock time).
Worker Lifecycle
Enqueue Work
↓
Waiting
↓
Constraints Met
↓
Execute
↓
Success
Retry
Failure
The system decides the best time to run it.
Part 11 — Constraints
Imagine:
Upload photos only when:
Wi-Fi
↓
Charging
↓
Battery OK
WorkManager supports constraints such as:
- Network type
- Charging state
- Battery level (not low)
- Storage availability (not low)
- Device idle (via underlying schedulers where applicable)
This prevents unnecessary battery drain.
Example
Sync Photos
↓
Requires Wi-Fi
↓
Wait
↓
Wi-Fi Available
↓
Run
The app doesn’t need to constantly monitor Wi-Fi.
Part 12 — Chaining Work
Suppose:
Download
↓
Resize Image
↓
Upload
↓
Notify User
Each step depends on the previous one.
WorkManager supports chaining dependent work requests.
Parallel Work
Imagine:
Upload A
Upload B
Upload C
Run simultaneously.
Then:
Merge Results
WorkManager supports combining chains and parallel execution.
Part 13 — Retry Policies
Suppose:
Upload
↓
No Internet
Failure.
Retry?
Yes.
But:
Retry
↓
Retry
↓
Retry
Forever?
No.
WorkManager supports retry policies including exponential backoff, allowing retries to become less frequent over time.
Part 14 — Battery Optimization
Android aggressively protects battery.
Techniques include:
- Doze Mode
- App Standby
- Background execution limits
- Alarm batching
- Job batching
Your app must cooperate with the operating system.
Trying to bypass these systems generally leads to poor user experience and may violate platform expectations.
Doze Mode
Suppose:
Phone sits on a table overnight.
Screen off.
Unused.
Android enters Doze.
During Doze:
- Network access is limited
- Jobs are deferred
- Alarms are deferred (with some exceptions)
- CPU wake-ups are minimized
The system periodically opens maintenance windows for deferred work.
App Standby
Imagine:
User hasn’t opened your app in weeks.
Android reduces:
- Background activity
- Network opportunities
- Job execution frequency
Frequently used apps receive more opportunities.
Part 15 — Choosing the Right API
This is one of the most common interview questions.
| Task | Recommended API |
|---|---|
| Upload a photo eventually | WorkManager |
| Daily database sync | WorkManager (Periodic) |
| Music playback | Foreground Service |
| GPS navigation | Foreground Service |
| Alarm clock | AlarmManager |
| Interactive communication with another app component | Bound Service |
| Short UI-related async task | Coroutine (viewModelScope, lifecycleScope) |
The key is understanding user expectations and system guarantees.
Part 16 — Complete Example
Suppose the user takes a photo.
Capture Photo
│
▼
Save Locally (Room/File)
│
▼
Enqueue WorkManager
│
▼
Wait for Wi-Fi
│
▼
Upload
│
▼
Server Response
│
▼
Update Local Database
│
▼
Flow Emits
│
▼
Compose Updates UI
Notice how this combines:
- Room
- WorkManager
- Coroutines
- Flow
- MVVM
- Repository
Everything you’ve learned so far works together.
Part 17 — Services vs WorkManager
This is another favorite interview topic.
| Feature | Service | WorkManager |
|---|---|---|
| Immediate execution | ✅ | Usually deferred (though expedited work exists with limits) |
| Guaranteed completion | ❌ | ✅ (best-effort, persistent scheduling) |
| Lifecycle aware | ❌ | Managed by system |
| Survives process death | Depends | Yes (work is persisted) |
| Good for user-visible ongoing work | ✅ (Foreground Service) | ❌ |
| Good for deferred background work | ❌ | ✅ |
Common Mistakes
❌ Using a Service for everything
Many tasks belong in WorkManager instead.
❌ Doing heavy work on a Service’s main thread
A Service is not a worker thread.
Always move expensive work to coroutines or other background execution.
❌ Starting long-running background services without user visibility
Modern Android heavily restricts background services.
❌ Expecting exact execution time from WorkManager
WorkManager guarantees eventual execution, not exact scheduling.
❌ Ignoring battery constraints
Respect Doze, App Standby, and scheduling constraints.
❌ Assuming your process will always stay alive
Android can terminate your process at almost any time when it’s no longer important.
Design for recovery.
Mental Model
Imagine a logistics company.
Customer Request
│
▼
Dispatcher (WorkManager)
│
┌─────┴────────────┐
▼ ▼
Truck Ready? Driver Available?
│ │
└─────────┬────────┘
▼
Deliver Package
The dispatcher doesn’t send the truck immediately if conditions aren’t right.
It waits until the constraints are satisfied.
That’s exactly how WorkManager behaves.
Best Practices
- Use WorkManager for deferrable, guaranteed background work.
- Use Foreground Services only for user-visible ongoing tasks.
- Keep Services lightweight and move heavy work off the main thread.
- Apply constraints to avoid wasting battery and data.
- Design work to be idempotent (safe to retry).
- Persist important work so it survives process death.
- Respect Android’s background execution policies rather than trying to circumvent them.
Interview Questions
- Why can Android kill your app’s process?
- What is the difference between a process and a thread?
- What is a Service, and what are its limitations?
- Compare Started Services and Bound Services.
- When should you use a Foreground Service?
- What is WorkManager, and how does it differ from JobScheduler?
- What are WorkManager constraints?
- What is Doze Mode?
- Why shouldn’t WorkManager be used for exact timing?
- How would you choose between a coroutine, Service, Foreground Service, AlarmManager, and WorkManager?
Module 15 Summary
You now understand Android’s background execution model:
- Android manages process lifecycles to balance performance, memory, and battery.
- Services perform work without a UI but are not background threads.
- Foreground Services support long-running, user-visible tasks.
- Broadcast Receivers respond to system events.
- AlarmManager schedules time-based events.
- WorkManager is the preferred API for reliable, deferrable background work.
- Constraints help Android optimize battery usage.
- Doze Mode and App Standby influence when background work can run.
At this stage, you can design applications that continue working reliably even when the user leaves the app or the device conditions change.
Your Progress So Far
You have now covered the major foundations of Android development:
- Android Fundamentals
- Activity & Fragment Lifecycle
- UI with Views & Compose
- Intents & Navigation
- State & Lifecycle Management
- Architecture Components
- RecyclerView / Lists / Lazy Layouts
- Data Handling & Storage Basics
- Advanced UI & Material Design
- MVVM & Clean Architecture
- Coroutines & Flow
- Dependency Injection (Hilt)
- Networking (Retrofit & OkHttp)
- Room & Offline-First Data
- Background Work & Scheduling
You now have the knowledge required to understand how a production-grade Android application is structured and how its major subsystems interact.
Next Module: Testing (Unit Testing, Instrumentation, UI Testing & Test Architecture)
Module 16 shifts from building features to verifying correctness.
You’ll learn:
- Why testing matters in large codebases.
- The testing pyramid.
- Unit vs integration vs instrumentation tests.
- JUnit fundamentals.
- Mocking with Mockito and MockK.
- Fake implementations and test doubles.
- Testing ViewModels, Repositories, and Use Cases.
- Coroutine testing with
runTest. - Testing
FlowandStateFlow. - UI testing with Espresso and Jetpack Compose Test APIs.
- Dependency injection for tests.
- Best practices for writing maintainable, deterministic tests.
This is the module that helps transform working code into reliable, maintainable software—a hallmark of senior Android engineering.