سلام. خوش اومدید😊
اینجا قسمت اول اموزش Work Manager توی اندروید هستش که توی این قسمت به معرفی، معماری و یه مثال ساده از Work Manager میپردازیم. خب بریم ببینیم چه خبره..
گاهی اوقات ممکنه به سناریو هایی توی اپ بخوریم که نیازه یه کاری در پس زمینه جدا از Life Cycle اپ انجام بشه. یعنی حتی اگه اپ بسته شد تسک ما انجام بشه. برای همچین مواقعی اندروید Work Manager رو معرفی کرده. Work Manager بخشی از ابزار های Jetpack هستش که برای اولین بار توی کنفرانس Google I/O در سال 2018 معرفی شد.
در واقع Work Manager برای تسک هایی ساخته شده که شما نیاز دارید کاری در Background Thread انجام بشه و این انجام شدنه تضمینی و قطعی باشه. برای مثالش میتونیم sync کردن اطلاعات با دیتابیس، آپلود/دانلود فایل ها، ارسال نوتیفیکیشن و غیره رو مثال بزنیم و همچنین میتونید این تسک رو بهش زمان اجرا بدید که در اون زمان اجرا بشه (به صورت تقریبی).
پس میشه گفت:
به صورت کلی Work Manager ابزاریه که میشه با اون یه سری تسک تعریف کرد که اون تسک به صورت تقریبی در زمان تعیین شده و در صورت وجود شرایط تعیین شده در بک گراند و خارج از اپ اجرا بشه.
شاید سوال بشه در اینجا منظورمون از شرایط تعیین شده چیه. ببینید توی Work Manager میتونید یه سری Constraint تعریف کنید . Constraint یعنی شرایط خاصی که میخوایم تسک ما تنها زمانی که این شرایط مهیاست اجرا بشه، برای نمونه این تسک مثلا فقط وقتی که گوشی توی شارژه یا حافظه کافی داره یا اینترنتش روشنه و ... اجرا بشه. وقتی موقع اجرای کد های شما فرا برسه اول این Constraint ها توسط Work Manager چک میشه، اگه برقرار بود که خب کدتون اجرا میشه اما در غیر این صورت Work Manager منتظر میمونه تا تمامی Constraint هایی که معین کردید برقرار بشه و بعد اجرا میکنه.
بیاید توی کد با Work Manager اشنا شیم.
خب قدم صفر اینه که Work Manager رو به پروژه اضافه کنیم. پس این تیکه کد رو باید توی build.gradle بذارید..
dependencies { val work_version = "2.9.1" implementation("androidx.work:work-runtime-ktx:$work_version") }
حالا اول از همه باید یه کلاس بسازیم که کدای اون تسک ما (که از این به بعد بهش میگیم Worker) رو توش بنویسیم.
class UploadWorker(appContext: Context, workerParams: WorkerParameters): Worker(appContext, workerParams) { override fun doWork(): Result { uploadImages() return Result.success() } }
خب همونطور که میبینید من یه کلاس UploadWorker ساختم که از Worker ارث بری میکنه. کلاس Worker یه تابع داره که باید override بشه به اسم doWork . توی این تابع ما عملیاتی که میخوایم این Worker انجام بده رو مینویسیم.
خب میبینید که این تابع ازمون میخواد که یه کلاس Result برگردونیم. Result نتیجه Worker ماست که 3 تا حالت داره : Success , Failed , Retry.
وقتی نتیجه رو Retry برمیگردونید این Worker یه بار دیگه وقتی که شرایط مهیا بود اجرا میشه. البته به صورت پیشفرض بعد از سه بار Retry کردن Worker شما خودکار Failed میشه و دیگه اجرا نمیشه.
خب حالا که Worker رو ساختیم بریم ازش استفاده کنیم.
val uploadWorkRequest: WorkRequest = OneTimeWorkRequestBuilder<UploadWorker>() .build() WorkManager .getInstance(myContext) .enqueue(uploadWorkRequest)
این نمونه کدی هستش که توی ViewModel باید باشه. بریم بخش بخش بررسیش کنیم.
خب اول از همه یه WorkRequest داریم تعریف میکنیم. WorkRequest ها دو نوع دارن OneTimeWorkRequest و PeriodicWorkRequest.
توی PeriodicWorkRequest شما تعریف میکنید که Worker من به صورت دوره ای مثلا هر ساعت یک بار باید اجرا بشه اما توی OneTimeWorkRequest شما میگید که Worker من نیاز به یک بار اجرا داره و بعد از Success یا Failed شدن کارش تموم میشه.
که خب برای UploadWorker ما فقط نیاز داریم که Worker یه بار کارشو انجام بده پس از OneTimeWorkRequest استفاده میکنیم و به عنوان ورودی Worker ای که ساختیم رو بهش میدیم و Build میکنیمش. قبل Build میتونستیم یه تنظیماتی به ریکوئستمون بدیم مثل همون Constraint هایی که گفتم، ولی فعلا بدون هیچ چیز اضافه ای کارو پیش میبریم.
حالا با استفاده از کلاس WorkManager (که یه Singleton هستش) بعد از اینکه Context رو بهش دادیم درخواست اجرای WorkRequest رو با استفاده از enqueue ثبت میکنیم.
خب بیایم ببینیم حالا چه اتفاقی میوفته. الان که ما یه Work رو ثبت کردیم، سیستم منابع خودش رو (مثلا چقد رم و CPU درگیره) رو حساب میکنه. اگه شرایط اوکی بود که خب در همون لحظه Worker ما اجرا میشه اما اگه کمبودی توی منابع باشه یا پردازش های دیگه ای توی الویت باشن، سیستم Worker مارو نگه میداره تا وقتی که شرایط به نرمال برسه و بعد اجرا میکنه. برای همینه که اصولا شما وقتی با Work Manager کار میکنید نباید توقع اجرای درلحظه Worker خودتون باشید و همیشه باید درنظر بگیرید مقداری تاخیر در اجرا وجود داره.
سیستم Work Manager اینجوری کار میکنه
شما میایید یه ریکوئست رو enqueue میکنید. بخش Internal TaskExecutor میاد اونو توی دیتابیس Work Manager (که همه ریکوئست های اپ ها توش ذخیره شده) سیو میکنه. حالا وقتی که شرایط مهیا شد (زمان اجرای شما فرا رسید - Constraint ها برقرار بود - منابع سیستم مناسب بود) Internal TaskExecutor به کلاس WorkerFactory میگه که Worker مربوط به شما رو بسازه و متد doWork اونو صدا بزنه که درنهایت به اجرای کد های شما ختم میشه.
خب تا همینجا قسمت اول آموزش Work Manager تموم میشه. توی قسمت بعدی به مقایسش با ابزار های دیگه میپردازیم.
اگه پست رو دوست داشتید حتما لایک کنید. برای حمایت بیشتر از من هم میتونید از اینجا coffeebede.com/n9ne یه قهوه مهمونم کنید که بهترین حمایت ممکنه ❤️