WorkManager به شما اجازه می دهد تا یک WorkRequest
پس از اینکه قبلاً در صف قرار داده اید، به روز کنید. این اغلب در برنامههای بزرگتری که مکرراً محدودیتها را تغییر میدهند یا نیاز به بهروزرسانی کارگران خود در حال پرواز دارند، ضروری است. از WorkManager نسخه 2.8.0، API updateWork()
ابزاری برای انجام این کار است.
متد updateWork()
به شما این امکان را میدهد که جنبههای خاصی از یک WorkRequest
را بدون نیاز به گذراندن فرآیند لغو دستی و قرار دادن یک درخواست جدید در نوبت تغییر دهید. این روند توسعه را تا حد زیادی ساده می کند.
از لغو کار خودداری کنید
به طور کلی باید از لغو یک WorkRequest موجود و قرار دادن یک درخواست جدید خودداری کنید. انجام این کار میتواند منجر به تکرار برخی کارها توسط برنامه شود و میتواند به نوشتن مقدار قابل توجهی کد اضافی نیاز داشته باشد.
مثال های زیر را در نظر بگیرید که در آن لغو یک درخواست کاری می تواند مشکلاتی را ایجاد کند:
- درخواست Back-end: اگر
Worker
در حالی که در حال محاسبه یک بار برای ارسال به سرور است، لغو کنید،Worker
جدید باید از نو شروع کند و بار بالقوه گران قیمت را دوباره محاسبه کند. - زمانبندی: اگر یک
PeriodicWorkRequest
لغو میکنید و میخواهید کهPeriodicWorkRequest
جدید در همان زمانبندی اجرا شود، باید یک فاصله زمانی محاسبه کنید تا اطمینان حاصل کنید که زمان اجرای جدید با درخواست کاری قبلی مطابقت دارد.
API updateWork()
به شما این امکان را میدهد که محدودیتهای درخواست کاری و سایر پارامترها را بدون مشکل لغو کردن و قرار دادن یک درخواست جدید بهروزرسانی کنید.
چه زمانی کار را لغو کنیم
مواردی وجود دارد که باید مستقیماً یک WorkRequest
لغو کنید نه اینکه updateWork()
را فراخوانی کنید. این همان کاری است که باید انجام دهید وقتی می خواهید ماهیت اساسی کاری را که در صف قرار داده اید تغییر دهید.
زمان به روز رسانی کار
برنامه عکسی را تصور کنید که روزانه از عکس های کاربر نسخه پشتیبان تهیه می کند. یک PeriodicWorkRequest
برای انجام این کار در نوبت قرار داده است. WorkRequest
دارای محدودیت هایی است که نیاز به شارژ شدن دستگاه و اتصال به WiFi دارد.
با این حال، کاربر تنها به مدت 20 دقیقه در روز دستگاه خود را با استفاده از شارژر سریع شارژ می کند. در این حالت، برنامه ممکن است بخواهد WorkRequest
را بهروزرسانی کند تا محدودیت شارژ را کاهش دهد، به طوری که حتی اگر دستگاه کاملاً شارژ نشده باشد، همچنان بتواند عکسها را آپلود کند.
در این شرایط میتوانید از متد updateWork()
برای بهروزرسانی محدودیتهای درخواست کاری استفاده کنید.
نحوه به روز رسانی کار
متد updateWork()
وسیله ای ساده برای به روز رسانی یک WorkRequest
موجود، بدون نیاز به لغو و در صف قرار دادن یک درخواست جدید، فراهم می کند.
برای استفاده از کار در صف به روز رسانی مراحل زیر را دنبال کنید:
- شناسه موجود برای کار در نوبت را دریافت کنید : شناسه WorkRequest را که میخواهید بهروزرسانی کنید، دریافت کنید. میتوانید این شناسه را با هر یک از APIهای
getWorkInfo
بازیابی کنید، یا بهطور دستی شناسه را از WorkRequest اولیه برای بازیابی بعدی با ویژگی عمومیWorkRequest.id
، قبل از قرار دادن آن در صف بازیابی کنید. - ایجاد WorkRequest جدید : یک
WorkRequest
جدید ایجاد کنید و ازWorkRequest.Builder.setID()
برای تنظیم شناسه آن برای مطابقت باWorkRequest
موجود استفاده کنید. - Set constraints : از
WorkRequest.Builder.setConstraints()
برای عبور از محدودیت های جدید WorkManager استفاده کنید. - فراخوانی updateWork : WorkRequest جدید را به
updateWork()
ارسال کنید.
نمونه کار را به روز کنید
در اینجا یک نمونه کد کد در Kotlin آمده است که نحوه استفاده از updateWork()
برای تغییر محدودیت های باتری WorkRequest
مورد استفاده برای آپلود عکس ها نشان می دهد:
suspend fun updatePhotoUploadWork() {
// Get instance of WorkManager.
val workManager = WorkManager.getInstance(context)
// Retrieve the work request ID. In this example, the work being updated is unique
// work so we can retrieve the ID using the unique work name.
val photoUploadWorkInfoList = workManager.getWorkInfosForUniqueWork(
PHOTO_UPLOAD_WORK_NAME
).await()
val existingWorkRequestId = photoUploadWorkInfoList.firstOrNull()?.id ?: return
// Update the constraints of the WorkRequest to not require a charging device.
val newConstraints = Constraints.Builder()
// Add other constraints as required here.
.setRequiresCharging(false)
.build()
// Create new WorkRequest from existing Worker, new constraints, and the id of the old WorkRequest.
val updatedWorkRequest: WorkRequest =
OneTimeWorkRequestBuilder<MyWorker>()
.setConstraints(newConstraints)
.setId(existingWorkRequestId)
.build()
// Pass the new WorkRequest to updateWork().
workManager.updateWork(updatedWorkRequest)
}
نتیجه را اداره کنید
updateWork()
یک ListenableFuture<UpdateResult>
برمی گرداند. UpdateResult
داده شده می تواند یکی از چندین مقدار را داشته باشد که مشخص می کند WorkManager قادر به اعمال تغییرات شما بوده است یا خیر. همچنین نشان می دهد که چه زمانی توانسته تغییر را اعمال کند.
برای اطلاعات بیشتر، به مرجع updateWork()
و UpdateResult
مراجعه کنید.
کار را با نسلها دنبال کنید
هر بار که یک WorkRequest
به روز می کنید، تولید آن یک افزایش می یابد. این به شما امکان می دهد دقیقاً کدام WorkRequest
در حال حاضر در صف قرار گرفته است را پیگیری کنید. نسلها هنگام مشاهده، ردیابی و آزمایش درخواستهای کاری، کنترل بیشتری در اختیار شما قرار میدهند.
برای دریافت تولید WorkRequest
، مراحل زیر را دنبال کنید:
- WorkInfo : با
WorkManager.getWorkInfoById()
تماس بگیرید تا نمونه ای ازWorkInfo
مربوط بهWorkRequest
شما را بازیابی کنید.- می توانید یکی از چندین روشی که
WorkInfo
برمی گرداند فراخوانی کنید. برای اطلاعات بیشتر، به مرجع WorkManager مراجعه کنید.
- می توانید یکی از چندین روشی که
- getGeneration :
getGeneration()
را در نمونهWorkInfo
فراخوانی کنید.Int
بازگشتی مربوط به تولیدWorkRequest
است.- توجه داشته باشید که فیلد یا ویژگی تولید وجود ندارد، فقط متد
WorkInfo.getGeneration()
وجود دارد.
- توجه داشته باشید که فیلد یا ویژگی تولید وجود ندارد، فقط متد
نمونه تولید آهنگ
در زیر نمونه ای از پیاده سازی گردش کار شرح داده شده در بالا برای بازیابی تولید یک WorkRequest
است.
// Get instance of WorkManager.
val workManager = WorkManager.getInstance(context)
// Retrieve WorkInfo instance.
val workInfo = workManager.getWorkInfoById(oldWorkRequestId)
// Call getGeneration to retrieve the generation.
val generation = workInfo.getGeneration()
سیاست های به روز رسانی کار
قبلاً، راهحل پیشنهادی برای بهروزرسانی کار دورهای، قرار دادن یک PeriodicWorkRequest
با خطمشی ExistingPeriodicWorkPolicy.REPLACE
بود. اگر PeriodicWorkRequest
معلقی با همان id
منحصر به فرد وجود داشته باشد، درخواست کار جدید آن را لغو و حذف می کند. این خط مشی اکنون به نفع گردش کار با استفاده از ExistingPeriodicWorkPolicy.UPDATE
منسوخ شده است.
برای مثال، هنگام استفاده از enqueueUniquePeriodicWork
با PeriodicWorkRequest
، می توانید PeriodicWorkRequest
جدید را با خط مشی ExistingPeriodicWorkPolicy.UPDATE
مقداردهی اولیه کنید. اگر PeriodicWorkRequest
معلقی با همین نام منحصر به فرد وجود داشته باشد، WorkManager آن را به مشخصات جدید به روز می کند. به دنبال این گردش کار، نیازی به استفاده از updateWork()
نیست.