Aayush Gupta
Migrating from Foreground
Service to WorkManager
Migrating From Foreground Services To WorkManager
• Independent Contractor
• Android Developer @ The Calyx
Institute, working on CalyxOS
• Senior Sta
ff
Member, DevRel @
XDA Developers (Forums)
• FOSS Developer & Contributor
About Me
3
Index
• Running background tasks in Android
• Introduction to WorkManager
• WorkManager in action
4
Running Background Tasks
Golden Days of Background Tasks
• Simple & easy, no need for
noti
fi
cations or permission
• Deprecated from Android 8.0+,
will crash app if used
• System apps can still run
background services (not-
recommended)
Service
6
This is Was The Way
• The de-facto way to run
background tasks now,
backwards compatible too
• Needs an ongoing noti
fi
cation
and bunch of permissions
• Android 12 blocks starting FGS
from background unless a
permitted use case
Foreground Service
7
Foreground Service
It’s Still Relevant Though
• Since Android 14, Foreground Service types are required as well as a
dedicated permission for the speci
fi
c type
• Additionally, Android 14 recommends migrating to WorkManager for data-
sync related jobs
• Android 15 will impose 6 hour time limit on data-sync type services
• Other than data-sync related jobs, Foreground Services are still the preferred
way to run background jobs
8
Introduction to WorkManager
WorkManager
The Cool Kid in the Block
• The primary recommended API for background processing
• Built-upon the Job Scheduler, Foreground Service, and more APIs
• Simple to use and manage
• Compatible with both Java and Kotlin, no dependency upon play services
• Allows to specify multiple constraints to the work as well
• One time and periodic are some of the most used work types
10
Expedited Work
Right Now, Hopefully
• Expedited work runs immediately on triggering
• Requires specifying setExpedited() method while building work
• A
ff
ected by App Standby Quotas and Doze restrictions
• Choice to drop work or run as non-expedited on quota exhaustion
• Periodic work cannot be expedited
11
Long-Running Work
10 Minutes Not Enough?
• Works are allowed a time-limit of 10 minutes by the OS
• Long-running work should be considered in case more time is required
• Requires calling setForeground() and overriding getForegroundInfo() methods
• Delegated to FGS above Android 12
• A
ff
ected by FGS restrictions too (permissions, constraints, etc)
12
WorkManager in Action
Constraints
Work, But When?
• WorkManager allows specifying several constraints for works
• Build with Constraints.Builder() and apply using setConstraints() method
• Developers can restrict running works based on metered/unmetered data,
battery levels, device activity and more
• Fine-grained network control coming in WorkManager 2.10
• Possible to update existing work constraints too
14
private const val TAG = "UpdateWorker"
private const val UPDATE_WORKER = "UPDATE_WORKER"
fun scheduleAutomatedCheck(context: Context) {
Log.i(TAG,"Scheduling periodic app updates!")
WorkManager.getInstance(context)
.enqueueUniquePeriodicWork(UPDATE_WORKER, KEEP, buildUpdateWork(context))
}
private fun buildUpdateWork(context: Context): PeriodicWorkRequest {
val updateCheckInterval = Preferences.getInteger(
context,
PREFERENCE_UPDATES_CHECK_INTERVAL,
3
).toLong()
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.UNMETERED)
.setRequiresBatteryNotLow(true)
if (isMAndAbove()) constraints.setRequiresDeviceIdle(true)
return PeriodicWorkRequestBuilder<UpdateWorker>(
repeatInterval = updateCheckInterval,
repeatIntervalTimeUnit = HOURS,
flexTimeInterval = 30,
flexTimeIntervalUnit = MINUTES
).setConstraints(constraints.build()).build()
}
Working
The Time is Now
• Developers can do their task in the doWork() method
• Automatically ran in background thread
• Returns a Result in the end
16
override suspend fun doWork(): Result {
Log.i(TAG, "Cleaning cache")
PathUtil.getOldDownloadDirectories(appContext).forEach { downloadDir -> // Downloads
Log.i(TAG, "Deleting old unused download directory: $downloadDir")
downloadDir.deleteRecursively()
}
PathUtil.getDownloadDirectory(appContext).listFiles()?.forEach { download -> // com.example.app
// Delete if the download directory is empty
if (download.listFiles().isNullOrEmpty()) {
Log.i(TAG, "Removing empty download directory for ${download.name}")
download.deleteRecursively(); return@forEach
}
download.listFiles()!!.forEach { versionCode -> // 20240325
if (versionCode.listFiles().isNullOrEmpty()) {
// Purge empty non-accessible directory
Log.i(TAG, "Removing empty directory for ${download.name}, ${versionCode.name}")
versionCode.deleteRecursively()
} else {
versionCode.deleteIfOld()
}
}
}
return Result.success()
}
Sharing Data with/from Workers
This and That
• Possible to share data with Workers using setInputData() method
• Also possible to share data from Workers using setProgress() method
• Shared data can be observed from the UI using LiveData or Kotlin Flows
• Data can be built with Data.Builder()
18
private fun trigger(download: Download) {
val inputData = Data.Builder()
.putString(DOWNLOAD_DATA, gson.toJson(download))
.build()
val work = OneTimeWorkRequestBuilder<DownloadWorker>()
.addTag(DOWNLOAD_WORKER)
.addTag("$PACKAGE_NAME:${download.packageName}")
.addTag("$VERSION_CODE:${download.versionCode}")
.addTag(if (download.isInstalled) DOWNLOAD_UPDATE else DOWNLOAD_APP)
.setExpedited(OutOfQuotaPolicy.DROP_WORK_REQUEST)
.setInputData(inputData)
.build()
// Ensure all app downloads are unique to preserve individual records
WorkManager.getInstance(context)
.enqueueUniqueWork(
"${DOWNLOAD_WORKER}/${download.packageName}",
ExistingWorkPolicy.KEEP, work
)
}
Final Thoughts
Work or Not?
• Good but not perfect replacement for FGS with data-sync tasks
• Just another yearly migration
20
Thank You!

More Related Content

PPTX
mobile development with androiddfdgdfhdgfdhf.pptx
PDF
【Unite 2017 Tokyo】C#ジョブシステムによるモバイルゲームのパフォーマンス向上テクニック
PDF
Analysing in depth work manager
 
PDF
ITB_2023_Human-Friendly_Scheduled_Tasks_Giancarlo_Gomez.pdf
PPTX
Bots on guard of sdlc
PDF
GoDocker presentation
PPTX
Quartz Scheduler
PPTX
Running Airflow Workflows as ETL Processes on Hadoop
mobile development with androiddfdgdfhdgfdhf.pptx
【Unite 2017 Tokyo】C#ジョブシステムによるモバイルゲームのパフォーマンス向上テクニック
Analysing in depth work manager
 
ITB_2023_Human-Friendly_Scheduled_Tasks_Giancarlo_Gomez.pdf
Bots on guard of sdlc
GoDocker presentation
Quartz Scheduler
Running Airflow Workflows as ETL Processes on Hadoop

Similar to Migrating From Foreground Services To WorkManager (20)

PPTX
Alternate for scheduled apex using flow builder
PPTX
#SPFestSea Introduction to #Azure #Functions v2
PPTX
Azure Functions in Action #CodePaLOUsa
PDF
Gradle - From minutes to seconds: minimizing build times
PDF
ICONUK 2013 - An XPager's Guide to Process Server-Side Jobs on IBM® Domino®
PPTX
An XPager's Guide to Process Server-Side Jobs on Domino
ODP
Java Concurrency, Memory Model, and Trends
PDF
2016 09-dev opsjourney-devopsdaysoslo
PDF
COScheduler
PDF
Android concurrency
PDF
Analysing in depth work manager
PPTX
AngularJS One Day Workshop
PDF
Java EE 7 Recipes for Concurrency - JavaOne 2014
PDF
Revolutionizing Task Scheduling in ColdBox
PPT
Late and Early binding in c++
PDF
[Struyf] Automate Your Tasks With Azure Functions
PDF
Matheus Albuquerque "The best is yet to come: the Future of React"
PPTX
Job schedulers android
PPTX
#SPFestDC #Azure #Functions V2: What's new and getting started
PPTX
Using Modern Browser APIs to Improve the Performance of Your Web Applications
Alternate for scheduled apex using flow builder
#SPFestSea Introduction to #Azure #Functions v2
Azure Functions in Action #CodePaLOUsa
Gradle - From minutes to seconds: minimizing build times
ICONUK 2013 - An XPager's Guide to Process Server-Side Jobs on IBM® Domino®
An XPager's Guide to Process Server-Side Jobs on Domino
Java Concurrency, Memory Model, and Trends
2016 09-dev opsjourney-devopsdaysoslo
COScheduler
Android concurrency
Analysing in depth work manager
AngularJS One Day Workshop
Java EE 7 Recipes for Concurrency - JavaOne 2014
Revolutionizing Task Scheduling in ColdBox
Late and Early binding in c++
[Struyf] Automate Your Tasks With Azure Functions
Matheus Albuquerque "The best is yet to come: the Future of React"
Job schedulers android
#SPFestDC #Azure #Functions V2: What's new and getting started
Using Modern Browser APIs to Improve the Performance of Your Web Applications
Ad

More from Aayush Gupta (8)

PDF
Writing OPass in Kotlin MultiPlatform Mobile
PDF
[Droidcon Uganda] Working With SELinux On Android
PDF
Building An Unofficial Client For XDA Developers
PDF
Exploring App Installation APIs in Android
PPTX
Third-party App Stores on Android.pptx.pdf
PPTX
Writing OS Updater App for Android
PPTX
Implementing Configurable Device Security With Security Levels.pptx
PPTX
Diving into Android Enterprise APIs with CalyxOS.pptx
Writing OPass in Kotlin MultiPlatform Mobile
[Droidcon Uganda] Working With SELinux On Android
Building An Unofficial Client For XDA Developers
Exploring App Installation APIs in Android
Third-party App Stores on Android.pptx.pdf
Writing OS Updater App for Android
Implementing Configurable Device Security With Security Levels.pptx
Diving into Android Enterprise APIs with CalyxOS.pptx
Ad

Recently uploaded (20)

PDF
Soil Improvement Techniques Note - Rabbi
PDF
August 2025 - Top 10 Read Articles in Network Security & Its Applications
PPT
INTRODUCTION -Data Warehousing and Mining-M.Tech- VTU.ppt
PPTX
Chemical Technological Processes, Feasibility Study and Chemical Process Indu...
PDF
ChapteR012372321DFGDSFGDFGDFSGDFGDFGDFGSDFGDFGFD
PPTX
ASME PCC-02 TRAINING -DESKTOP-NLE5HNP.pptx
PDF
III.4.1.2_The_Space_Environment.p pdffdf
PPTX
communication and presentation skills 01
PPTX
tack Data Structure with Array and Linked List Implementation, Push and Pop O...
PDF
null (2) bgfbg bfgb bfgb fbfg bfbgf b.pdf
PDF
Abrasive, erosive and cavitation wear.pdf
PDF
Accra-Kumasi Expressway - Prefeasibility Report Volume 1 of 7.11.2018.pdf
PDF
Influence of Green Infrastructure on Residents’ Endorsement of the New Ecolog...
PDF
Categorization of Factors Affecting Classification Algorithms Selection
PDF
SMART SIGNAL TIMING FOR URBAN INTERSECTIONS USING REAL-TIME VEHICLE DETECTI...
PDF
Visual Aids for Exploratory Data Analysis.pdf
PPT
Total quality management ppt for engineering students
PDF
Artificial Superintelligence (ASI) Alliance Vision Paper.pdf
PPTX
"Array and Linked List in Data Structures with Types, Operations, Implementat...
PPTX
Software Engineering and software moduleing
Soil Improvement Techniques Note - Rabbi
August 2025 - Top 10 Read Articles in Network Security & Its Applications
INTRODUCTION -Data Warehousing and Mining-M.Tech- VTU.ppt
Chemical Technological Processes, Feasibility Study and Chemical Process Indu...
ChapteR012372321DFGDSFGDFGDFSGDFGDFGDFGSDFGDFGFD
ASME PCC-02 TRAINING -DESKTOP-NLE5HNP.pptx
III.4.1.2_The_Space_Environment.p pdffdf
communication and presentation skills 01
tack Data Structure with Array and Linked List Implementation, Push and Pop O...
null (2) bgfbg bfgb bfgb fbfg bfbgf b.pdf
Abrasive, erosive and cavitation wear.pdf
Accra-Kumasi Expressway - Prefeasibility Report Volume 1 of 7.11.2018.pdf
Influence of Green Infrastructure on Residents’ Endorsement of the New Ecolog...
Categorization of Factors Affecting Classification Algorithms Selection
SMART SIGNAL TIMING FOR URBAN INTERSECTIONS USING REAL-TIME VEHICLE DETECTI...
Visual Aids for Exploratory Data Analysis.pdf
Total quality management ppt for engineering students
Artificial Superintelligence (ASI) Alliance Vision Paper.pdf
"Array and Linked List in Data Structures with Types, Operations, Implementat...
Software Engineering and software moduleing

Migrating From Foreground Services To WorkManager

  • 1. Aayush Gupta Migrating from Foreground Service to WorkManager
  • 3. • Independent Contractor • Android Developer @ The Calyx Institute, working on CalyxOS • Senior Sta ff Member, DevRel @ XDA Developers (Forums) • FOSS Developer & Contributor About Me 3
  • 4. Index • Running background tasks in Android • Introduction to WorkManager • WorkManager in action 4
  • 6. Golden Days of Background Tasks • Simple & easy, no need for noti fi cations or permission • Deprecated from Android 8.0+, will crash app if used • System apps can still run background services (not- recommended) Service 6
  • 7. This is Was The Way • The de-facto way to run background tasks now, backwards compatible too • Needs an ongoing noti fi cation and bunch of permissions • Android 12 blocks starting FGS from background unless a permitted use case Foreground Service 7
  • 8. Foreground Service It’s Still Relevant Though • Since Android 14, Foreground Service types are required as well as a dedicated permission for the speci fi c type • Additionally, Android 14 recommends migrating to WorkManager for data- sync related jobs • Android 15 will impose 6 hour time limit on data-sync type services • Other than data-sync related jobs, Foreground Services are still the preferred way to run background jobs 8
  • 10. WorkManager The Cool Kid in the Block • The primary recommended API for background processing • Built-upon the Job Scheduler, Foreground Service, and more APIs • Simple to use and manage • Compatible with both Java and Kotlin, no dependency upon play services • Allows to specify multiple constraints to the work as well • One time and periodic are some of the most used work types 10
  • 11. Expedited Work Right Now, Hopefully • Expedited work runs immediately on triggering • Requires specifying setExpedited() method while building work • A ff ected by App Standby Quotas and Doze restrictions • Choice to drop work or run as non-expedited on quota exhaustion • Periodic work cannot be expedited 11
  • 12. Long-Running Work 10 Minutes Not Enough? • Works are allowed a time-limit of 10 minutes by the OS • Long-running work should be considered in case more time is required • Requires calling setForeground() and overriding getForegroundInfo() methods • Delegated to FGS above Android 12 • A ff ected by FGS restrictions too (permissions, constraints, etc) 12
  • 14. Constraints Work, But When? • WorkManager allows specifying several constraints for works • Build with Constraints.Builder() and apply using setConstraints() method • Developers can restrict running works based on metered/unmetered data, battery levels, device activity and more • Fine-grained network control coming in WorkManager 2.10 • Possible to update existing work constraints too 14
  • 15. private const val TAG = "UpdateWorker" private const val UPDATE_WORKER = "UPDATE_WORKER" fun scheduleAutomatedCheck(context: Context) { Log.i(TAG,"Scheduling periodic app updates!") WorkManager.getInstance(context) .enqueueUniquePeriodicWork(UPDATE_WORKER, KEEP, buildUpdateWork(context)) } private fun buildUpdateWork(context: Context): PeriodicWorkRequest { val updateCheckInterval = Preferences.getInteger( context, PREFERENCE_UPDATES_CHECK_INTERVAL, 3 ).toLong() val constraints = Constraints.Builder() .setRequiredNetworkType(NetworkType.UNMETERED) .setRequiresBatteryNotLow(true) if (isMAndAbove()) constraints.setRequiresDeviceIdle(true) return PeriodicWorkRequestBuilder<UpdateWorker>( repeatInterval = updateCheckInterval, repeatIntervalTimeUnit = HOURS, flexTimeInterval = 30, flexTimeIntervalUnit = MINUTES ).setConstraints(constraints.build()).build() }
  • 16. Working The Time is Now • Developers can do their task in the doWork() method • Automatically ran in background thread • Returns a Result in the end 16
  • 17. override suspend fun doWork(): Result { Log.i(TAG, "Cleaning cache") PathUtil.getOldDownloadDirectories(appContext).forEach { downloadDir -> // Downloads Log.i(TAG, "Deleting old unused download directory: $downloadDir") downloadDir.deleteRecursively() } PathUtil.getDownloadDirectory(appContext).listFiles()?.forEach { download -> // com.example.app // Delete if the download directory is empty if (download.listFiles().isNullOrEmpty()) { Log.i(TAG, "Removing empty download directory for ${download.name}") download.deleteRecursively(); return@forEach } download.listFiles()!!.forEach { versionCode -> // 20240325 if (versionCode.listFiles().isNullOrEmpty()) { // Purge empty non-accessible directory Log.i(TAG, "Removing empty directory for ${download.name}, ${versionCode.name}") versionCode.deleteRecursively() } else { versionCode.deleteIfOld() } } } return Result.success() }
  • 18. Sharing Data with/from Workers This and That • Possible to share data with Workers using setInputData() method • Also possible to share data from Workers using setProgress() method • Shared data can be observed from the UI using LiveData or Kotlin Flows • Data can be built with Data.Builder() 18
  • 19. private fun trigger(download: Download) { val inputData = Data.Builder() .putString(DOWNLOAD_DATA, gson.toJson(download)) .build() val work = OneTimeWorkRequestBuilder<DownloadWorker>() .addTag(DOWNLOAD_WORKER) .addTag("$PACKAGE_NAME:${download.packageName}") .addTag("$VERSION_CODE:${download.versionCode}") .addTag(if (download.isInstalled) DOWNLOAD_UPDATE else DOWNLOAD_APP) .setExpedited(OutOfQuotaPolicy.DROP_WORK_REQUEST) .setInputData(inputData) .build() // Ensure all app downloads are unique to preserve individual records WorkManager.getInstance(context) .enqueueUniqueWork( "${DOWNLOAD_WORKER}/${download.packageName}", ExistingWorkPolicy.KEEP, work ) }
  • 20. Final Thoughts Work or Not? • Good but not perfect replacement for FGS with data-sync tasks • Just another yearly migration 20