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() نیست.