WorkManager คือไลบรารี Android Jetpack ที่ออกแบบมาสำหรับการดำเนินงานที่ถูกเลื่อนและพื้นหลังแบบรับประกันการดำเนินการ แตกต่างจาก Service หรือ JobScheduler ตรงที่ WorkManager จัดการวงจรชีวิตของงาน: เริ่มใหม่เมื่อล้มเหลว ปรับตามเวอร์ชัน Android และพิจารณาข้อจำกัดของอุปกรณ์ ตาม Android Developers, 2026 WorkManager เป็นโซลูชันที่ต้องการสำหรับการดำเนินการพื้นหลังส่วนใหญ่ในการพัฒนา Android สมัยใหม่
ประเด็นสำคัญ
WorkManager เป็นส่วนหนึ่งของ Android Jetpack ไลบรารีสำหรับจัดการงานพื้นหลังที่ต้องดำเนินการอย่างรับประกัน ไม่ว่าแอปจะอยู่เบื้องหน้าหรือถูกปิดโดยผู้ใช้ ไลบรารีรองรับ API 14+ และเลือกกลไกการดำเนินการที่เหมาะสมโดยอัตโนมัติ: JobScheduler บน Android 5+, BroadcastReceiver + AlarmManager บนเวอร์ชันเก่ากว่า
คุณสมบัติหลักของ WorkManager คือ การรับประกันการดำเนินการ หากงานไม่เสร็จสมบูรณ์เนื่องจากการรีบูตอุปกรณ์ การสิ้นสุดแอป หรือการขัดข้อง WorkManager จะเริ่มใหม่เมื่อมีโอกาสแรก ซึ่งทำให้ไลบรารีเป็นตัวเลือกที่เหมาะสำหรับงานที่สำคัญต่อการดำเนินการ: การส่งข้อมูลวิเคราะห์ การซิงโครไนซ์ฐานข้อมูล การอัปโหลดล็อก
แตกต่างจาก Background Service ตรงที่ WorkManager ไม่จำเป็นต้องจัดการเธรดและวงจรชีวิต ไลบรารีสร้างพูลเธรดเอง จัดการ Doze Mode พิจารณาเวอร์ชัน Android และให้ API ที่เป็นหนึ่งเดียวโดยไม่ขึ้นกับระดับ API รองรับ Coroutine และ RxJava ผ่าน CoroutineWorker และ RxWorker ตามลำดับ
WorkManager รองรับ LiveData ในตัวสำหรับติดตามสถานะงาน เมธอด getWorkInfoByIdLiveData ส่งคืน LiveData<WorkInfo> ที่อัปเดตเมื่อมีการเปลี่ยนแปลงสถานะ: ENQUEUED, RUNNING, SUCCEEDED, FAILED, CANCELLED ซึ่งช่วยให้ส่วนประกอบ UI ตอบสนองต่อการเปลี่ยนแปลงโดยไม่ต้องสอบถามตัวกำหนดเวลาด้วยตนเองและไม่มีการรั่วไหลของหน่วยความจำต้องขอบคุณส่วนประกอบ Lifecycle-aware
WorkManager.getInstance(context)
.getWorkInfoByIdLiveData(syncRequest.id)
.observe(viewLifecycleOwner) { workInfo ->
when (workInfo.state) {
WorkInfo.State.SUCCEEDED ->
showSuccess()
WorkInfo.State.FAILED ->
showError(workInfo.outputData)
else ->
showProgress()
}
}
สถาปัตยกรรม ของ WorkManager สร้างขึ้นรอบคลาสพื้นฐานสามคลาส: Worker, WorkRequest และ WorkManager Worker มีตรรกะของงาน WorkRequest อธิบายพารามิเตอร์การดำเนินการ และ WorkManager จัดการคิวและการกำหนดเวลา ไลบรารีใช้ฐานข้อมูล Room ภายในเพื่อเก็บสถานะของงานทั้งหมด
Worker คือคลาสนามธรรมที่มีเมธอดเดียว doWork ซึ่งถูกเรียกบนเธรดพื้นหลัง เมธอดส่งคืน ListenableWorker.Result — SUCCESS, FAILURE หรือ RETRY WorkRequest เชื่อม Worker กับพารามิเตอร์: หมดเวลา แท็ก หน่วงเวลาเริ่มต้น และข้อจำกัด
class SyncWorker(
context: Context,
params: WorkerParameters
) : Worker(context, params) {
override fun doWork(): Result {
return try {
val api = RetrofitClient.api
val response = api.syncData()
Result.success()
} catch (e: Exception) {
Result.retry()
}
}
}
WorkManager กำหนดเวลางานอย่างสม่ำเสมอโดยไม่ขึ้นกับเวอร์ชัน Android เมื่อเรียก enqueue ไลบรารีจะบันทึกงานใน Room ประเมินเงื่อนไขปัจจุบัน และเลือกเวลาดำเนินการที่เหมาะสมที่สุด เบื้องหลังอาจใช้ JobScheduler, AlarmManager หรือตัวกำหนดเวลาของตัวเอง — นักพัฒนาไม่ต้องกังวลเกี่ยวกับเรื่องนี้
val syncRequest = OneTimeWorkRequestBuilder<SyncWorker>()
.setInitialDelay(15, TimeUnit.MINUTES)
.addTag("sync")
.build()
WorkManager.getInstance(context)
.enqueue(syncRequest)
WorkManager รองรับคำขอการดำเนินการสองประเภท: แบบครั้งเดียวและแบบระยะเวลา การเลือกประเภทขึ้นอยู่กับสถานการณ์: งานควรทำงานครั้งเดียวหรือทำซ้ำตามช่วงเวลาที่กำหนด
OneTimeWorkRequest ออกแบบมาสำหรับงานที่ควรดำเนินการเพียงครั้งเดียว ซึ่งอาจเป็นการส่งล็อก การซิงโครไนซ์ข้อมูลหลังการตรวจสอบสิทธิ์ การดาวน์โหลดการกำหนดค่าเมื่อเริ่มครั้งแรก การหน่วงเวลาตั้งค่าผ่าน setInitialDelay และข้อจำกัดผ่าน setConstraints
PeriodicWorkRequest เหมาะสำหรับงานที่ทำซ้ำโดยมีช่วงเวลาขั้นต่ำ 15 นาที ไลบรารีรับประกันว่าช่วงเวลาระหว่างการทำงานจะไม่น้อยกว่าที่กำหนด แต่อาจนานขึ้นเนื่องจากข้อจำกัดของอุปกรณ์ สำหรับงานที่มีความถี่น้อยกว่า 15 นาที ให้ใช้ Handler หรือ Timer ใน Foreground Service
| พารามิเตอร์ | OneTimeWorkRequest | PeriodicWorkRequest |
|---|---|---|
| ความถี่ | ครั้งเดียว | ซ้ำ (ขั้นต่ำ 15 นาที) |
| จำนวน | 1 การดำเนินการ | จนกว่าจะยกเลิก |
| หน่วงเวลา | setInitialDelay | setInitialDelay |
| ห่วงโซ่ | รองรับ | ไม่ |
| การใช้งาน | ดาวน์โหลด, ซิงค์ | ตรวจสอบ, การสอบถาม |
ข้อจำกัด ใน WorkManager ช่วยให้คุณกำหนดเงื่อนไขที่สามารถเริ่มงานได้: การเชื่อมต่อเครือข่าย (NetworkType), ระดับแบตเตอรี่ (batteryNotLow), สถานะพื้นที่จัดเก็บ (StorageNotLow) และโหมดไม่ได้ใช้งาน (DeviceIdle) งานจะไม่เริ่มจนกว่าจะปฏิบัติตามข้อจำกัดทั้งหมด
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.setRequiresCharging(true)
.setRequiresBatteryNotLow(true)
.build()
val request = OneTimeWorkRequestBuilder<ImageUploadWorker>()
.setConstraints(constraints)
.build()
ห่วงโซ่ ช่วยให้คุณจัดระเบียบการดำเนินงานแบบต่อเนื่องหรือขนาน beginWith เริ่มห่วงโซ่ จากนั้นเพิ่ม Worker ถัดไปที่จะดำเนินการหลังจากเสร็จสิ้นงานก่อนหน้าสำเร็จ สำหรับการดำเนินการแบบขนาน ให้ใช้ workManager.enqueue(listOf(request1, request2))
WorkManager.getInstance(context)
.beginWith(compressWorker)
.then(uploadWorker)
.then(cleanupWorker)
.enqueue()
// compress -> upload -> cleanup ตามลำดับ
JobScheduler ถูกนำมาใช้ใน Android 5 (API 21) ในฐานะบริการระบบสำหรับกำหนดเวลางานพื้นหลัง WorkManager เข้ามาแทนที่ โดยเสนอ API ข้ามแพลตฟอร์มพร้อมการย้ายข้อมูลอัตโนมัติและความสามารถเพิ่มเติม: ห่วงโซ่ การรับประกันการดำเนินการ แท็ก การสังเกตสถานะผ่าน LiveData
เมื่อย้ายจาก JobScheduler ไปยัง WorkManager คุณต้องแปลง JobService เป็น Worker แทนที่ JobInfo ด้วย WorkRequest และ Context.getSystemService ด้วย API ของ WorkManager WorkManager จัดการปัญหาความเข้ากันได้โดยอัตโนมัติและจัดการ Doze Mode ถูกต้องกว่าการใช้งาน JobScheduler ด้วยตนเอง ขั้นตอนการย้าย: 1) สร้างคลาส Worker, 2) สร้าง WorkRequest ด้วยเงื่อนไขเดียวกัน, 3) ลบ JobService และ JobInfo ออกจากโค้ดและ manifest
WorkManager รองรับแนวคิดของงานที่ไม่ซ้ำผ่าน ExistingWorkPolicy หากมีงานตามชื่อที่กำหนดอยู่แล้ว นโยบายจะกำหนดพฤติกรรม: KEEP (ไม่สร้างใหม่), REPLACE (แทนที่งานที่มีอยู่), APPEND (เพิ่มต่อท้ายห่วงโซ่) และ APPEND_OR_REPLACE UniqueWorkRequest สะดวกสำหรับงานที่ไม่ควรทำซ้ำ: การซิงโครไนซ์ฐานข้อมูล การดาวน์โหลดการกำหนดค่า การส่งชุดข้อมูลวิเคราะห์
WorkManager.getInstance(context)
.enqueueUniqueWork(
"sync_data",
ExistingWorkPolicy.KEEP,
syncRequest
)
CoroutineWorker รองรับกลไก setProgress ซึ่งช่วยให้ส่งผ่านผลลัพธ์การดำเนินการระหว่างกลาง ซึ่งมีประโยชน์สำหรับการดำเนินการระยะยาว: การดาวน์โหลดไฟล์ขนาดใหญ่ การประมวลผลภาพเป็นชุด การย้ายฐานข้อมูล UI สามารถสมัครรับการอัปเดตผ่าน getWorkInfosByTagLiveData และแสดงความคืบหน้าแบบเรียลไทม์ เมธอด ForegroundInfo ยังมีให้สำหรับเรียกใช้ Worker เป็น Foreground Service พร้อมการแจ้งเตือนหากงานควรปรากฏแก่ผู้ใช้
class ProgressWorker(
context: Context,
params: WorkerParameters
) : CoroutineWorker(context, params) {
override suspend fun doWork(): Result {
val total = 100
for (i in 1..total) {
setProgress(
workDataOf("progress" to i)
)
}
return Result.success()
}
}
WorkManager รองรับการถ่ายโอนข้อมูลระหว่าง Workers ผ่าน InputData และ OutputData InputData ถูกสร้างขึ้นระหว่างการสร้าง WorkRequest ผ่าน Data.Builder และส่งต่อไปยัง Worker ผ่าน inputData หลังจากการดำเนินการ Worker สร้าง OutputData ผ่าน workDataOf หรือ Data.Builder และส่งคืนพร้อมกับ Result.success(outputData) Worker ถัดไปในห่วงโซ่ได้รับ outputData ของงานก่อนหน้าเป็น inputData ของตัวเอง ข้อมูลถูกจัดเก็บในรูปแบบคีย์-ค่าพร้อมรองรับชนิดพื้นฐาน: String, Int, Long, Boolean, Double ขนาดสูงสุดของ Data คือ 10 KB
ในทางปฏิบัติ หลายโครงการใช้ WorkManager เป็นตัวกำหนดเวลางานพื้นหลังเพียงตัวเดียว Google แนะนำให้ย้าย JobService ทั้งหมดที่มีอยู่ไปยัง WorkManager โดยเฉพาะในแอปที่รองรับ Android 4.4 (API 19) และต่ำกว่า ซึ่ง JobScheduler ไม่พร้อมใช้งานและ WorkManager ใช้กลไกสำรองผ่าน AlarmManager และ BroadcastReceiver สำหรับการทดสอบ WorkManager มี TestListenableWorkerBuilder และ TestWorkerBuilder ซึ่งช่วยให้ทดสอบ Workers ใน JUnit tests โดยไม่ต้องมีตัวกำหนดเวลาจริง
สำหรับการทดสอบ WorkManager ให้ใช้ TestListenableWorkerBuilder จาก AndroidX Test ซึ่งช่วยให้เรียกใช้ Workers ในสภาพแวดล้อมที่แยกออกมาและตรวจสอบ Result ที่ส่งคืน ไลบรารีรองรับ JUnit และ Robolectric อย่างสมบูรณ์สำหรับการทดสอบหน่วยโดยไม่ต้องมีตัวกำหนดเวลาจริง โดยรวมแล้ว WorkManager เหมาะสำหรับ 80% ของงานที่เคยใช้ Service หรือ JobScheduler
คำถามที่พบบ่อย
ใช่, WorkManager รับประกันการดำเนินการแม้หลังจากการรีบูต ไลบรารีบันทึกงานที่ไม่สมบูรณ์ทั้งหมดในฐานข้อมูล Room และกู้คืนโดยใช้ BroadcastReceiver ที่ทำงานหลังจากระบบบูต
Worker ทำงานบนเธรดพื้นหลังโดยไม่รองรับ coroutine หรือ RxJava CoroutineWorker ใช้ coroutine ของ Kotlin พร้อมรองรับฟังก์ชัน suspend และการยกเลิกผ่านขอบเขต coroutine RxWorker ทำงานกับ Observable และ Single เหมาะสำหรับห่วงโซ่แบบรีแอกทีฟ
ใช้ workManager.cancelWorkById(id) หรือ workManager.cancelAllWorkByTag("tag") ไลบรารียังมีเมธอด cancelUniqueWork("name") สำหรับยกเลิกงานที่ไม่ซ้ำตามชื่อที่กำหนด
ช่วงเวลาขั้นต่ำสำหรับ PeriodicWorkRequest คือ 15 นาที ข้อจำกัดนี้กำหนดโดย Google เพื่อป้องกันการใช้แบตเตอรี่มากเกินไป หากงานต้องทำงานบ่อยขึ้น ให้ใช้ Foreground Service หรือ Handler กับตัวจับเวลา
ใช่, WorkManager รองรับ API 14+ บนอุปกรณ์ที่ไม่มี JobScheduler (ต่ำกว่า API 21) ไลบรารีใช้การผสมผสานระหว่าง AlarmManager และ BroadcastReceiver สำหรับการกำหนดเวลางาน ทำให้ WorkManager เป็นโซลูชันสากลสำหรับงานพื้นหลัง
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ