WorkManager เป็นไลบรารีสำหรับการจัดกำหนดการและดำเนินการทำงานเบื้องหลังที่เลื่อนเวลาได้ ใน Android เราแนะนำให้ใช้แทน Firebase JobDispatcher คำแนะนำต่อไปนี้จะช่วยแนะนำขั้นตอนการย้ายข้อมูล Firebase การนำ JobDispatcher ไปใช้ใน WorkManager
การตั้งค่า Gradle
หากต้องการนำเข้าไลบรารี WorkManager ลงในโปรเจ็กต์ Android ให้เพิ่มพารามิเตอร์ ทรัพยากร Dependency ที่แสดงใน การเริ่มต้นใช้งาน WorkManager
จาก JobService ไปยังผู้ปฏิบัติงาน
FirebaseJobDispatcher
ใช้คลาสย่อยของ
JobService
เป็นจุดเริ่มต้นสำหรับกำหนด
งานที่ต้องทำ คุณอาจ
โดยใช้ JobService
โดยตรง หรือใช้
SimpleJobService
JobService
จะมีลักษณะดังนี้
Kotlin
import com.firebase.jobdispatcher.JobParameters import com.firebase.jobdispatcher.JobService class MyJobService : JobService() { override fun onStartJob(job: JobParameters): Boolean { // Do some work here return false // Answers the question: "Is there still work going on?" } override fun onStopJob(job: JobParameters): Boolean { return false // Answers the question: "Should this job be retried?" } }
Java
import com.firebase.jobdispatcher.JobParameters; import com.firebase.jobdispatcher.JobService; public class MyJobService extends JobService { @Override public boolean onStartJob(JobParameters job) { // Do some work here return false; // Answers the question: "Is there still work going on?" } @Override public boolean onStopJob(JobParameters job) { return false; // Answers the question: "Should this job be retried?" } }
หากคุณกำลังใช้ SimpleJobService
คุณจะลบล้าง onRunJob()
ได้
ซึ่งแสดงผลประเภท @JobResult int
ความแตกต่างหลักคือเมื่อคุณใช้ JobService
โดยตรง, onStartJob()
ในเทรดหลัก และเป็นความรับผิดชอบของแอปในการนำออก
ไปยังชุดข้อความพื้นหลังได้ ในทางกลับกัน ถ้าคุณใช้
SimpleJobService
บริการดังกล่าวมีหน้าที่รับผิดชอบในการดำเนินงานของคุณ
เทรดพื้นหลัง
WorkManager มีแนวคิดที่คล้ายกัน หน่วยพื้นฐานของงานใน WorkManager คือ
ListenableWorker
มี
ประเภทย่อยที่มีประโยชน์อื่นๆ ของผู้ปฏิบัติงาน เช่น
Worker
RxWorker
และ CoroutineWorker
(เมื่อ
ที่ใช้ Kotlin coroutines)
JobService แมปกับ ListenableWorker
หากคุณใช้ JobService
โดยตรง ผู้ปฏิบัติงานที่แมปด้วยจะเป็น
ListenableWorker
ถ้าคุณใช้ SimpleJobService
คุณควรใช้
Worker
แทน
ให้ใช้ตัวอย่างด้านบน (MyJobService
) และดูว่าเราจะแปลงได้อย่างไร
เป็น ListenableWorker
Kotlin
import android.content.Context import androidx.work.ListenableWorker import androidx.work.ListenableWorker.Result import androidx.work.WorkerParameters import com.google.common.util.concurrent.ListenableFuture class MyWorker(appContext: Context, params: WorkerParameters) : ListenableWorker(appContext, params) { override fun startWork(): ListenableFuture<ListenableWorker.Result> { // Do your work here. TODO("Return a ListenableFuture<Result>") } override fun onStopped() { // Cleanup because you are being stopped. } }
Java
import android.content.Context; import androidx.work.ListenableWorker; import androidx.work.ListenableWorker.Result; import androidx.work.WorkerParameters; import com.google.common.util.concurrent.ListenableFuture; class MyWorker extends ListenableWorker { public MyWorker(@NonNull Context appContext, @NonNull WorkerParameters params) { super(appContext, params); } @Override public ListenableFuture<ListenableWorker.Result> startWork() { // Do your work here. Data input = getInputData(); // Return a ListenableFuture<> } @Override public void onStopped() { // Cleanup because you are being stopped. } }
หน่วยการทำงานพื้นฐานของ WorkManager คือ ListenableWorker
เหมือน
JobService.onStartJob()
, มีการเรียก startWork()
ในเทรดหลัก ที่นี่
MyWorker
ใช้งาน ListenableWorker
และแสดงผลอินสแตนซ์ของ
ListenableFuture
ซึ่งใช้เพื่อส่งสัญญาณแจ้งการทำงานเสร็จสมบูรณ์แบบไม่พร้อมกัน คุณควรเลือก
สร้างชุดข้อความของตัวเองที่นี่
ListenableFuture
ที่นี่จะแสดงประเภท ListenableWorker.Result
ในท้ายที่สุด
ซึ่งอาจเป็น Result.success()
, Result.success(Data outputData)
,
Result.retry()
, Result.failure()
หรือ Result.failure(Data outputData)
สำหรับ
โปรดดูข้อมูลเพิ่มเติมในหน้าข้อมูลอ้างอิงสำหรับ
ListenableWorker.Result
มีการเรียก onStopped()
เพื่อส่งสัญญาณว่า ListenableWorker
จำเป็นต้องหยุด
เนื่องจากไม่สามารถบรรลุข้อจำกัดได้ (เช่น เนื่องจาก
เครือข่าย ไม่สามารถใช้งานได้อีกต่อไป) หรือเนื่องจากเมธอด WorkManager.cancel…()
คือ
โทรออก อาจมีการเรียก onStopped()
หากระบบปฏิบัติการตัดสินใจปิด
ทำงานด้วยเหตุผลบางอย่าง
SimpleJobService แมปไปยังผู้ปฏิบัติงาน
เมื่อใช้ SimpleJobService
ผู้ปฏิบัติงานด้านบนจะมีลักษณะดังต่อไปนี้
Kotlin
import android.content.Context; import androidx.work.Data; import androidx.work.ListenableWorker.Result; import androidx.work.Worker; import androidx.work.WorkerParameters; class MyWorker(context: Context, params: WorkerParameters) : Worker(context, params) { override fun doWork(): Result { TODO("Return a Result") } override fun onStopped() { super.onStopped() TODO("Cleanup, because you are being stopped") } }
Java
import android.content.Context; import androidx.work.Data; import androidx.work.ListenableWorker.Result; import androidx.work.Worker; import androidx.work.WorkerParameters; class MyWorker extends Worker { public MyWorker(@NonNull Context appContext, @NonNull WorkerParameters params) { super(appContext, params); } @Override public Result doWork() { // Do your work here. Data input = getInputData(); // Return a ListenableWorker.Result Data outputData = new Data.Builder() .putString(“Key”, “value”) .build(); return Result.success(outputData); } @Override public void onStopped() { // Cleanup because you are being stopped. } }
ที่นี่ doWork()
จะส่งกลับอินสแตนซ์ของ ListenableWorker.Result
เพื่อส่งสัญญาณแจ้งงาน
การทำงานเสร็จพร้อมกัน ซึ่งคล้ายกับ SimpleJobService
ซึ่งกำหนดเวลา
งานในชุดข้อความในเบื้องหลัง
JobBuilder แมปไปยัง WorkRequest
FirebaseJobBuilder ใช้ Job.Builder
เพื่อแสดงข้อมูลเมตาของ Job
เครื่องมือจัดการงาน
ใช้ WorkRequest
เพื่อเติมเต็มบทบาทนี้
WorkManager มี WorkRequest
2 ประเภทดังนี้
OneTimeWorkRequest
และ
PeriodicWorkRequest
หากคุณกำลังใช้ Job.Builder.setRecurring(true)
คุณควร
สร้าง PeriodicWorkRequest
ใหม่ หรือไม่เช่นนั้น คุณควรใช้
OneTimeWorkRequest
มาดูกันว่าการตั้งเวลา Job
ที่ซับซ้อนด้วย FirebaseJobDispatcher
อาจมีอะไรบ้าง
มีลักษณะดังนี้
Kotlin
val input: Bundle = Bundle().apply { putString("some_key", "some_value") } val job = dispatcher.newJobBuilder() // the JobService that will be called .setService(MyService::class.java) // uniquely identifies the job .setTag("my-unique-tag") // one-off job .setRecurring(false) // don't persist past a device reboot .setLifetime(Lifetime.UNTIL_NEXT_BOOT) // start between 0 and 60 seconds from now .setTrigger(Trigger.executionWindow(0, 60)) // don't overwrite an existing job with the same tag .setReplaceCurrent(false) // retry with exponential backoff .setRetryStrategy(RetryStrategy.DEFAULT_EXPONENTIAL) .setConstraints( // only run on an unmetered network Constraint.ON_UNMETERED_NETWORK, // // only run when the device is charging Constraint.DEVICE_CHARGING ) .setExtras(input) .build() dispatcher.mustSchedule(job)
Java
Bundle input = new Bundle(); input.putString("some_key", "some_value"); Job myJob = dispatcher.newJobBuilder() // the JobService that will be called .setService(MyJobService.class) // uniquely identifies the job .setTag("my-unique-tag") // one-off job .setRecurring(false) // don't persist past a device reboot .setLifetime(Lifetime.UNTIL_NEXT_BOOT) // start between 0 and 60 seconds from now .setTrigger(Trigger.executionWindow(0, 60)) // don't overwrite an existing job with the same tag .setReplaceCurrent(false) // retry with exponential backoff .setRetryStrategy(RetryStrategy.DEFAULT_EXPONENTIAL) // constraints that need to be satisfied for the job to run .setConstraints( // only run on an unmetered network Constraint.ON_UNMETERED_NETWORK, // only run when the device is charging Constraint.DEVICE_CHARGING ) .setExtras(input) .build(); dispatcher.mustSchedule(myJob);
หากต้องการดำเนินการดังกล่าวด้วย WorkManager คุณจะต้องทำดังนี้
- สร้างข้อมูลอินพุตที่สามารถใช้เป็นอินพุตสำหรับ
Worker
- สร้าง
WorkRequest
ด้วยข้อมูลอินพุตและข้อจำกัดที่คล้ายกับ ที่กำหนดไว้ข้างต้นสำหรับFirebaseJobDispatcher
- จัดคิว
WorkRequest
การตั้งค่าอินพุตสำหรับผู้ปฏิบัติงาน
FirebaseJobDispatcher
ใช้ Bundle
เพื่อส่งข้อมูลอินพุตไปยัง JobService
WorkManager ใช้ Data
แทน สไตรค์
ที่จะกลายเป็น
Kotlin
import androidx.work.workDataOf val data = workDataOf("some_key" to "some_val")
Java
import androidx.work.Data; Data input = new Data.Builder() .putString("some_key", "some_value") .build();
การตั้งค่าข้อจำกัดสำหรับผู้ปฏิบัติงาน
FirebaseJobDispatcher
ใช้
Job.Builder.setConstaints(...)
มากำหนดข้อจำกัดในงาน WorkManager ใช้
Constraints
แทน
Kotlin
import androidx.work.* val constraints: Constraints = Constraints.Builder().apply { setRequiredNetworkType(NetworkType.CONNECTED) setRequiresCharging(true) }.build()
Java
import androidx.work.Constraints; import androidx.work.Constraints.Builder; import androidx.work.NetworkType; Constraints constraints = new Constraints.Builder() // The Worker needs Network connectivity .setRequiredNetworkType(NetworkType.CONNECTED) // Needs the device to be charging .setRequiresCharging(true) .build();
การสร้าง WorkRequest (OneTime หรือ Periodic)
คุณควรใช้เพื่อสร้าง OneTimeWorkRequest
และ PeriodicWorkRequest
OneTimeWorkRequest.Builder
และ PeriodicWorkRequest.Builder
หากต้องการสร้าง OneTimeWorkRequest
ซึ่งคล้ายกับ Job
ด้านบน คุณควร
ให้ทำดังนี้
Kotlin
import androidx.work.* import java.util.concurrent.TimeUnit val constraints: Constraints = TODO("Define constraints as above") val request: OneTimeWorkRequest = // Tell which work to execute OneTimeWorkRequestBuilder<MyWorker>() // Sets the input data for the ListenableWorker .setInputData(input) // If you want to delay the start of work by 60 seconds .setInitialDelay(60, TimeUnit.SECONDS) // Set a backoff criteria to be used when retry-ing .setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 30000, TimeUnit.MILLISECONDS) // Set additional constraints .setConstraints(constraints) .build()
Java
import androidx.work.BackoffCriteria; import androidx.work.Constraints; import androidx.work.Constraints.Builder; import androidx.work.NetworkType; import androidx.work.OneTimeWorkRequest; import androidx.work.OneTimeWorkRequest.Builder; import androidx.work.Data; // Define constraints (as above) Constraints constraints = ... OneTimeWorkRequest request = // Tell which work to execute new OneTimeWorkRequest.Builder(MyWorker.class) // Sets the input data for the ListenableWorker .setInputData(inputData) // If you want to delay the start of work by 60 seconds .setInitialDelay(60, TimeUnit.SECONDS) // Set a backoff criteria to be used when retry-ing .setBackoffCriteria(BackoffCriteria.EXPONENTIAL, 30000, TimeUnit.MILLISECONDS) // Set additional constraints .setConstraints(constraints) .build();
ความแตกต่างที่สำคัญในที่นี้คืองานของ WorkManager จะยังคงอยู่ตลอดทั่วทั้ง อุปกรณ์จะรีบูตโดยอัตโนมัติ
หากต้องการสร้าง PeriodicWorkRequest
คุณจะต้องทำดังนี้
Kotlin
val constraints: Constraints = TODO("Define constraints as above") val request: PeriodicWorkRequest = PeriodicWorkRequestBuilder<MyWorker>(15, TimeUnit.MINUTES) // Sets the input data for the ListenableWorker .setInputData(input) // Other setters .build()
Java
import androidx.work.BackoffCriteria; import androidx.work.Constraints; import androidx.work.Constraints.Builder; import androidx.work.NetworkType; import androidx.work.PeriodicWorkRequest; import androidx.work.PeriodicWorkRequest.Builder; import androidx.work.Data; // Define constraints (as above) Constraints constraints = ... PeriodicWorkRequest request = // Executes MyWorker every 15 minutes new PeriodicWorkRequest.Builder(MyWorker.class, 15, TimeUnit.MINUTES) // Sets the input data for the ListenableWorker .setInputData(input) . // other setters (as above) .build();
การกำหนดเวลางาน
ตอนนี้คุณก็ได้กำหนด Worker
และ WorkRequest
แล้ว คุณก็พร้อมที่จะ
กำหนดเวลางาน
ทุก Job
ที่กำหนดไว้ด้วย FirebaseJobDispatcher
มี tag
ซึ่งใช้เพื่อ
ระบุ Job
อย่างไม่ซ้ำกัน และยังทำให้แอปพลิเคชัน
ตัวจัดตารางเวลาหากอินสแตนซ์นี้ของ Job
ใช้เพื่อแทนที่สำเนาที่มีอยู่ของ
Job
โดยโทรไปที่ setReplaceCurrent
Kotlin
val job = dispatcher.newJobBuilder() // the JobService that will be called .setService(MyService::class.java) // uniquely identifies the job .setTag("my-unique-tag") // don't overwrite an existing job with the same tag .setRecurring(false) // Other setters... .build()
Java
Job myJob = dispatcher.newJobBuilder() // the JobService that will be called .setService(MyJobService.class) // uniquely identifies the job .setTag("my-unique-tag") // don't overwrite an existing job with the same tag .setReplaceCurrent(false) // other setters // ... dispatcher.mustSchedule(myJob);
เมื่อใช้ WorkManager คุณจะได้ผลลัพธ์เดียวกันได้โดยใช้
enqueueUniqueWork()
และ enqueueUniquePeriodicWork()
API (เมื่อใช้
OneTimeWorkRequest
และ PeriodicWorkRequest
ตามลำดับ) สำหรับข้อมูลเพิ่มเติม
โปรดดูหน้าอ้างอิงสำหรับ
WorkManager.enqueueUniqueWork()
และ WorkManager.enqueueUniquePeriodicWork()
ซึ่งจะมีลักษณะดังนี้
Kotlin
import androidx.work.* val request: OneTimeWorkRequest = TODO("A WorkRequest") WorkManager.getInstance(myContext) .enqueueUniqueWork("my-unique-name", ExistingWorkPolicy.KEEP, request)
Java
import androidx.work.ExistingWorkPolicy; import androidx.work.OneTimeWorkRequest; import androidx.work.WorkManager; OneTimeWorkRequest workRequest = // a WorkRequest; WorkManager.getInstance(myContext) // Use ExistingWorkPolicy.REPLACE to cancel and delete any existing pending // (uncompleted) work with the same unique name. Then, insert the newly-specified // work. .enqueueUniqueWork("my-unique-name", ExistingWorkPolicy.KEEP, workRequest);
กำลังยกเลิกงาน
เมื่อใช้ FirebaseJobDispatcher
คุณจะยกเลิกการทำงานได้โดยใช้สิ่งต่อไปนี้
Kotlin
dispatcher.cancel("my-unique-tag")
Java
dispatcher.cancel("my-unique-tag");
เมื่อใช้ WorkManager คุณจะใช้สิ่งต่อไปนี้ได้
Kotlin
import androidx.work.WorkManager WorkManager.getInstance(myContext).cancelUniqueWork("my-unique-name")
Java
import androidx.work.WorkManager; WorkManager.getInstance(myContext).cancelUniqueWork("my-unique-name");
กำลังเริ่มต้น WorkManager
ตามปกติ WorkManager จะเริ่มต้นทำงานเองโดยใช้ ContentProvider
หากต้องการควบคุมวิธีการจัดระเบียบและกำหนดเวลาของ WorkManager ได้มากขึ้น คุณสามารถดำเนินการต่อไปนี้
ปรับแต่งการกำหนดค่าและการเริ่มต้น WorkManager ได้