توسعه سرویس اندرویدی که هرگز متوقف نمیشود – راهنمای کاربردی
در این مقاله در مورد شیوه ساخت یک سرویس اندروید صحبت میکنیم که به صورت نامحدود اجرا شود. اگر به این بحث علاقهمند هستید با ما تا انتهای این راهنما همراه باشید.


بیان مسئله
به دلیل معرفی بحث بهینهسازی باتری که در نسخه 8.0 اندروید (API 28) معرفی شده است، سرویسهای پسزمینه اینک با محدودیت مهمی مواجه هستند. در واقع این سرویسها زمانی که اپلیکیشن برای مدتی در حالت پسزمینه بماند قطع میشوند و به این ترتیب ارزش خود را به عنوان سرویسی که باید به طور مداوم در حال اجرا باشند از دست میدهند.
بر اساس توصیههای اندروید ما باید از JobScheduler استفاده کنیم که به نظر میرسد کارکرد خوبی دارد و wakelock-ها را برای ما مدیریت میکند و زمانی که وظیفهای در حال اجرا است گوشی را بیدار حفظ میکند.
متأسفانه این راهحل نیز کار نمیکند. JobScheduler کارها را به نیابت از اندروید اجرا میکنند و زمانی که گوشی وارد حالت Doze میشود، بسامد این کارها نیز به تدریج کاهش مییابد. موضوع بدتر این است که اگر بخواهید به شبکه دسترسی پیدا کنید، برای مثال اگر میخواهید دادههایی را به سرور ارسال کنید، قادر به انجام این کار نخواهید بود. برای مطالعه فهرست محدودیتهای حالت DOZE به این صفحه (+) مراجعه کنید.
JobScheduler در صورتی که به دسترسی نداشتن به شبکه اهمیتی ندهید و کنترل کردن توالی کارها نیز چندان مهم نباشد به خوبی کار میکند. در این مقاله ما میخواهیم سرویسی بسازیم که با بسامد کاملاً خاصی کار میکند و هرگز متوقف نمیشود و از این رو این روش برای ما کار نمیکند.
سرویسهای پیشزمینه
اگر تاکنون در اینترنت به دنبال راهحلی برای این مشکل گشته باشید، به احتمال زیاد به این صفحه (+) از مستندات اندروید رسیدهاید. در این صفحه انواع مختلفی از سرویسهایی که اندروید ارائه میکند معرفی شدهاند. توضیح «سرویسهای پیشزمینه» (Foreground Service) به صورت زیر است:
سرویس پیشزمینه نوعی عملیات را اجرا میکند که در دید کاربر قرار دارد. برای نمونه یک اپلیکیشن صوتی میتواند از سرویس پیشزمینه برای پخش یک قطعه صوتی استفاده کند. سرویسهای پیشزمینه باید یک نوتیفیکیشن نمایش دهند. سرویسهای پیشزمینه حتی زمانی که کاربر با اپلیکیشن در تعامل نیست همچنان به اجرای خود ادامه میدهند. به نظر میرسد استفاده از سرویسهای پیشزمینه چاره حل مشکل ما است.
کدنویسی
ایجاد یک پردازش foreground service کار نسبتاً سرراستی است و از این رو در ادامه همه مراحل مورد نیاز برای ساخت یک سرویس پیشزمینه را توضیح میدهیم که هرگز متوقف نخواهد شد.
در صورتی که میخواهید مستقیم به کد دسترسی داشته باشید، میتوانند به این ریپازیتوری گیتهاب (+) مراجعه کنید.
افزودن برخی وابستگیها
ما در این مثال از کاتلین استفاده کنیم و بنابراین از کتابخانههای coroutines و Fuel برای درخواستهای HTTP کمک میگیریم. برای افزودن این وابستگیها باید آنها را به فایل build.gradle اضافه کنیم:
نوشتن سرویس
سرویسهای پیشزمینه نیاز به یک نوتیفیکیشن دارند که نمایش یابد تا کاربر از این که اپلیکیشن در حال اجرا است آگاهی یابد. توجه کنید که ما برخی از متدهای callback سرویس را که جنبههای کلیدی چرخه عمر سرویس را کنترل میکنند override کردهایم.
همچنین حتماً باید توجه کنید که ما از یک partial wakelock استفاده کردهایم و از این رو سرویس ما هرگز تحت تأثیر حالت Doze قرار نمیگیرد. به خاطر بسپارید که این وضعیت بر عمر باتری گوشی ما تأثیرگذار است و از این رو باید کاملاً بررسی کنیم که آیا این کاربرد از سوی هر گونه روش جایگزین دیگر اندروید برای اجرای پردازشها در پسزمینه قابل اجرا است یا نه.
برخی فراخوانیهای تابعهای کاربردی (log ،setServiceState) و برخی enum-های سفارشی در کد وجود دارند، اما جای نگرانی زیادی نیست. اگر میخواهید بدانید این موارد از کجا ناشی میشوند کافی است به ریپازیتوری مثال (+) نگاه کنید.
بررسی مانیفست اندروید
ما برای FOREGROUND_SERVICE ،INTERNET و WAKE_LOCK به برخی مجوزهای بیشتر نیاز داریم. مطمئن شوید که آنها را حتماً درج کردهاید، چون در غیر این صورت کار نمیکند. زمانی که آنها را در جای خود قرار دادید، باید سرویس خود را اعلان کنیم:
روش آغاز کردن سرویس
باید بسته به نسخه اندروید، سرویس خود را با متدهای مختلفی آغاز کنیم. در نسخههای اندروید زیر API 26 باید از startService استفاده کنیم و در موارد دیگر میبایست از startForegroundService استفاده شود.
در ادامه MainActivity ما را میبینید که صرفاً صفحهای با دو دکمه آغاز و توقف سرویس است. اینها تنها مواردی هستند که برای اجرای سرویس بیپایان نیاز داریم.
نکته مهم: آغاز سرویس در زمان بوت شدن اندروید
ما اینک سرویس بیپایانی داریم که بنا به خواست ما هر دقیقه یک بار یک درخواست شبکه ارسال میکند اما اگر کاربر گوشی را ریاستارت کند چطور؟ در این حالت سرویس ما در زمان بوت شدن اندروید به صورت خودکار اجرا نمیشود و این یک مشکل محسوب میشود. اما جای نگرانی نیست ما راهحلی برای این مسئله نیز یافتهایم. به این منظور یک BroadCastReceiver به نام StartReceiver میسازیم.
سپس Android Manifest را بار دیگر تغییر میدهیم و یک مجوز جدید به نام RECEIVE_BOOT_COMPLETED و کلاس BroadCastReceiver را اضافه میکنیم.
بدین ترتیب به پایان این راهنما میرسیم.
اگر این مطلب برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای برنامهنویسی اندروید
- گنجینه برنامه نویسی اندروید (Android)
- مجموعه آموزشهای برنامهنویسی
- ساخت اپلیکیشن لانچر اندروید — به زبان ساده
- نشت حافظه در اپلیکیشن های اندروید — از صفر تا صد
==













مقاله خوبیه مرسی از زحماتتون ولی یه سوال برام پیش اومد شما میگید که از partial wake lock استفاده کنیم ولی توی این لینک اومده که داز مود wake lock رو ایگنور میکنه
https://developer.android.com/training/monitoring-device-state/doze-standby