WorkManager in Android
What is WorkManager?
WorkManager is an API Android Jetpack provides for scheduling deferrable, asynchronous tasks that are expected to run reliably. It is especially suited for tasks that must be executed even if the app is killed or the device is rebooted.
Key features:
When Should You Use WorkManager?
Use WorkManager for tasks like:
Real-World Use Case: Compressing and Uploading Media
Let's walk through a practical example where WorkManager is used to:
1. Setting Up WorkManager
Add Dependencies
implementation "androidx.work:work-runtime-ktx:2.8.1"
Basic Workflow
WorkManager tasks are defined in a Worker class:
2. Full Implementation
Step 1: Compressing Media Files
We'll compress images using input/output streams (lightweight and dependency-free) and use FFmpeg (or placeholders) for video compression.
Step 2: Uploading Media Files
We'll upload files using Retrofit.
2.1 Worker Class
class PostUploadWorker(context: Context, params: WorkerParameters) : Worker(context, params) {
override fun doWork(): Result {
val mediaUris = inputData.getStringArray("media_uris") ?: return Result.failure()
return try {
// Step 1: Compress files
val compressedFiles = compressMediaFiles(mediaUris, applicationContext)
// Step 2: Upload files to the server
uploadFiles(compressedFiles)
Result.success() // Task successful
} catch (e: Exception) {
e.printStackTrace()
Result.retry() // Retry on failure
}
}
private fun compressMediaFiles(mediaUris: Array<String>, context: Context): List<File> {
val compressedFiles = mutableListOf<File>()
for (uri in mediaUris) {
val inputFile = File(uri) // Convert URI to File
val outputFile = File(context.cacheDir, "compressed_${inputFile.name}")
if (inputFile.extension == "jpg" || inputFile.extension == "png") {
compressImage(inputFile, outputFile, quality = 70)
} else if (inputFile.extension == "mp4") {
compressVideo(inputFile, outputFile)
}
compressedFiles.add(outputFile)
}
return compressedFiles
}
private fun compressImage(inputFile: File, outputFile: File, quality: Int = 80) {
val bitmap = BitmapFactory.decodeFile(inputFile.absolutePath)
FileOutputStream(outputFile).use { outputStream ->
bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream)
}
}
private fun compressVideo(inputFile: File, outputFile: File) {
// Placeholder for video compression logic
FileInputStream(inputFile).use { inputStream ->
FileOutputStream(outputFile).use { outputStream ->
inputStream.copyTo(outputStream)
}
}
}
private fun uploadFiles(files: List<File>) {
val retrofit = createRetrofitService()
val uploadService = retrofit.create(UploadService::class.java)
for (file in files) {
val requestBody = file.asRequestBody("multipart/form-data".toMediaType())
val filePart = MultipartBody.Part.createFormData("file", file.name, requestBody)
val response = uploadService.uploadMedia(filePart).execute()
if (!response.isSuccessful) throw Exception("Upload failed for ${file.name}")
}
}
private fun createRetrofitService(): Retrofit {
return Retrofit.Builder()
.baseUrl("https://your-api-endpoint.com/") // Replace with your server URL
.addConverterFactory(GsonConverterFactory.create())
.build()
}
}
interface UploadService {
@Multipart
@POST("upload")
fun uploadMedia(@Part file: MultipartBody.Part): Call<ResponseBody>
}
领英推荐
2.2 Scheduling the Work
You can schedule the WorkManager task using OneTimeWorkRequest:
fun schedulePostUpload(context: Context, mediaUris: List<String>) {
val inputData = Data.Builder()
.putStringArray("media_uris", mediaUris.toTypedArray())
.build()
val uploadWorkRequest = OneTimeWorkRequestBuilder<PostUploadWorker>()
.setInputData(inputData)
.build()
WorkManager.getInstance(context).enqueue(uploadWorkRequest)
}
2.3 Triggering the Task
When the user submits a post:
val mediaUris = listOf(
"/storage/emulated/0/Download/photo1.jpg",
"/storage/emulated/0/Download/video1.mp4"
)
schedulePostUpload(applicationContext, mediaUris)
When to Use Foreground Service:
Advantages:
Disadvantages:
When to Use WorkManager:
Advantages:
Disadvantages:
Conclusion
WorkManager is a powerful tool that helps Android developers handle background tasks reliably. In this article, we explored:
With this knowledge, you can confidently implement reliable background tasks in your Android applications. Let me know if you'd like further clarifications or enhancements.