Background Service — یک مؤلفه Android است که برای انجام عملیات طولانی در پسزمینه بدون واسط کاربر طراحی شده است. برخلاف Activity، Service حتی پس از کوچک شدن برنامه یا تغییر کاربر به برنامهای دیگر به کار خود ادامه میدهد. به استناد به Android Developers, 2026، سه نوع سرویس وجود دارد: Started Service، Bound Service و Foreground Service، هر کدام با چرخه زندگی و حوزه کاربردی خود.
نکات کلیدی
فهرست مطالب
Background Service (یا صرفاً Service) — یکی از چهار مؤلفه اصلی برنامه Android در کنار Activity، BroadcastReceiver و ContentProvider است. برخلاف Activity، Service اینترفیس دیداری ندارد و برای انجام عملیاتی که باید به طور مستقل از اینکه برنامه در پیش زمینه هست یا نه ادامه یابند طراحی شده است.
Service در ترافت اصلی (main thread) برنامه کار میکند، بنابراین هر عملیات مسدودکننده داخل آن نیازمند ایجاد یک ترافت جداگانه است. اگر این کار انجام نشود، سیستم ANR (Application Not Responding). برای عملیات ساده پسزمینه، Android IntentService را ارائه میدهد که به طور خودکار یک ترافت کاری ایجاد میکند. در پروژههای مدرن، توصیه میشود از کوروتینهای Kotlin با CoroutineScope داخل Service برای پردازش ناهمگام بدون بستن ترافت اصلی استفاده شود.
هدف اصلی Service — پخش موسیقی، دانلود فایلها، کار با درخواستهای شبکه، همگامسازی دادهها و سایر وظایفی است که باید پس از خروج کاربر از برنامه ادامه یابند. اما با انتشار Android 8، توسعهدهندگان باید با توجه به محدودیتهای کار در پسزمینه، آگاهانه بین انواع سرویسها انتخاب کنند.
Service چرخه زندگی خود را دارد که با Activity متفاوت است. آن چهار روش کلیدی را شامل میشود: onCreate، onStartCommand، onBind و onDestroy. درک این چرخه برای پیادهسازی درست وظایف پسزمینه بدون نشت حافظه ضروری است.
روش onCreate هنگام ایجاد سرویس، یکبار در طول عمر آن فراخوانده میشود. در آن منابع اولیهسازی میشوند: تایمرها، اتصالات پایگاه داده، سوکتها. روش onStartCommand هر بار با فراخوانی startService صدا زده میشود که امکان ارسال دستورات به سرویس در حال کار را فراهم میکند. مقدار بازگشتی رفتار سیستم را در وقت راهاندازی مجدد تعیین میکند.
class DownloadService : Service() {
override fun onCreate() {
super.onCreate()
initializeDownloader()
}
override fun onStartCommand(
intent: Intent?,
flags: Int,
startId: Int
): Int {
downloadFile(intent?.getStringExtra("url"))
return START_STICKY
}
override fun onBind(intent: Intent): IBinder? = null
}
onBind هنگام اتصال سرویس از طریق bindService فراخوانده میشود و یک شیء IBinder برای تعامل با مشتری برمیگرداند. این روش فقط برای Bound Service استفاده میشود. onDestroy — آخرین فراخوانی پیش از نابودی سرویس است. در آن تمامی منابع آزاد میشوند، ترافتها متوقف و وظایف لغو میشوند.
Android سه نوع Service ارائه میدهد، هر کدام برای سناریوی خود طراحی شده است. انتخاب نوع اشتباه میتواند منجر به کار ناپایدار برنامه یا مصرف بیشروی باتری شود.
Started Service با فراخوانی startService راهاندازی میشود و تا فراخوانی stopSelf یا stopService کار میکند. آن برای وظایفی مناسب است که باید فوراً انجام شوند: ارسال آنالیتیک، پردازش تصویر، دانلود یک فایل. پس از اتمام کار، سرویس خودکار متوقف میشود.
Bound Service یک رابط مشتری-سرور فراهم میکند که به Activity، Fragment یا سایر کامپوننتها امکان تعامل با سرویس را میدهد. سرویس تا وجود حداقل یک مشتری متصل زنده میماند. وقتی همه مشتریان جدا شوند، سرویس نابود میشود. Bound Service برای وظایفی که نیازمند ارتباط دوطرفه هستند مناسب است: پخشکننده موسیقی، ناوبری.
Foreground Service — یک Started Service با اعلان ثابت در نوبار وضعیت است. سیستم چنین سرویسی را فعال دانسته و حتی در صورت کمبود حافظه آن را نمیکشد. Foreground Service برای پخش موسیقی، ضبط صدا، ردیابی مکان و سایر وظایف مهم برای کاربر اجباری است.
| پارامتر | Started | Bound | Foreground |
|---|---|---|---|
| راهاندازی | startService | bindService | startForeground |
| عمر | تا stopSelf | تا وجود مشتریان | تا stopForeground |
| اعلان | نه | نه | اجباری |
| کشته میشود | بله | بله | نه |
| مثال | دانلود | پخشکننده | موسیقی |
ایجاد سرویس با اعلام کلاسی که از Service ارث میبرد و ثبت آن در AndroidManifest.xml آغاز میشود. بدون ثبت در مانیفست، سیستم نمیتواند سرویس را راهاندازی کند و هر فراخوانی startService منجر به استثنا خواهد شد.
// ثبت در AndroidManifest.xml
@SuppressLint("ForegroundServiceType")
class SyncService : Service() {
override fun onStartCommand(
intent: Intent?,
flags: Int,
startId: Int
): Int {
startForeground(
NOTIFICATION_ID,
createNotification()
)
performSync(intent)
return START_NOT_STICKY
}
}
برای راهاندازی سرویس از Activity یا Fragment از Intent با اشاره صریح به کلاس سرویس استفاده میشود. از Android 8 به بعد، برای Foreground Service مجوز FOREGROUND_SERVICE در مانیفست ضروری است.
// راهاندازی Started Service
val intent = Intent(this, SyncService::class.java)
intent.putExtra("action", "sync")
startService(intent)
// راهاندازی Foreground Service (Android 8+)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(intent)
} else {
startService(intent)
}
از Android 8 (API 26) گوگل محدودیتهای سختگیرانهای را بر سرویسهای پسزمینه اعمال کرده است. راهاندازی Service در پسزمینه (وقتی برنامه در پیش زمینه نیست) فقط در موارد استثنایی مجاز است: پس از دریافت اعلان فشاری، پس از راهاندازی دستگاه یا از طریق JobScheduler.
برای وظایف طولانی که نیازمند اجرای فوری نیستند، توصیه میشود از WorkManager یا JobScheduler استفاده کنید. اگر برنامه واقعاً به یک سرویس در حال کار نیاز دارد، تنها راه — Foreground Service با اعلانی که کاربر میبیند. راهاندازی سرویس در پسزمینه بدون اعلان توسط سیستم نادیده گرفته میشود.
JobIntentService — یک کلاس تخصصی است که در کتابخانه support برای کار در Android 5+ پدیدار شد. آن رفتار IntentService (ترافت کاری خودکار، پردازش متوالی) را با برنامهریزی از طریق JobScheduler ترکیب میکند. در Android 8+، JobIntentService از JobScheduler در زیر کپ استفاده میکند و در نسخههای کهنتر از Service عادی. این امکان پردازش یکسان وظایف پسزمینه را بدون بررسی اضافی نسخه Android فراهم میکند.
class UploadJobService : JobIntentService() {
companion object {
private const val JOB_ID = 1000
fun enqueueWork(context: Context, work: Intent) {
enqueueWork(
context,
UploadJobService::class.java,
JOB_ID,
work
)
}
}
override fun onHandleWork(intent: Intent) {
val fileUri = intent.getStringExtra("file_uri")
// اجرا در نخ پسزمینه
uploadFile(fileUri)
}
}
یکی از مشکلات رایج در کار با Background Service نشت حافظه است. از آنجا که Service میتواند بیشتر از Activity عمر کند، ارجاعات به Activity داخل Service (از طریق listener، callback یا broadcast) منجر به عدم قابلیت جمعآوری زباله برای کامپوننتهای UI میشود. برای ارتباط Service با UI توصیه میشود از WeakReference، ViewModel یا LiveData استفاده کنید. در onDestroy باید تمامی اشتراکها لغو، ترافتها متوقف و کورسرها بسته شوند.
انتخاب بین Background Service و WorkManager به سناریو بستگی دارد. Service برای وظایفی مناسب است که باید فوراً و به طور متوالی انجام شوند: پخش موسیقی، ضبط صدا، ردیابی GPS. WorkManager برای وظایف به تأخیر افتاده و تضمینی بهتر است: همگامسازی، ارسال آنالیتیک، آپلود لاگها. WorkManager از راهاندازی مجدد دستگاه جان سالم به در میآید، اما Service نمیتواند. Service میتواند Foreground با اعلان باشد، اما WorkManager در پسزمینه آرام کار میکند. در عمل، توسعهدهندگان هر دو رویکرد را ترکیب میکنند: Foreground Service برای وظایف حساس کاربر و WorkManager برای خدمات پسزمینه.
Android 12 یک پرچم android:foregroundServiceType را معرفی کرد که نیازمند تعیین نوع خدمت است: dataSync، camera، connectedDevice، location، mediaPlayback و غیره. تعیین نادرست نوع منجر به استثنا در زمان راهاندازی میشود. این رویه Background Service را برای کاربر و سیستم شفافتر میکند.
ثبت درست Service در مانیفست شامل ویژگیهای exported (دسترسی برای برنامههای خارجی)، foregroundServiceType (نوع خدمت پسزمینه در Android 12+) و permission است. برای Bound Service باید android:permission="android.permission.BIND_JOB_SERVICE" را برای JobIntentService اعلام کنید. بدون ثبت در مانیفست، هر فراخوانی startService یا bindService با استثنا خاتمه مییابد، بنابراین بررسی مانیفست اولین گام در عیبیابی مشکلات Service است.
سوالات متداول
Service در ترافت اصلی (UI Thread) برنامه اجرا میشود. هر عملیات مسدودکننده داخل onStartCommand یا onHandleIntent باید به یک ترافت جداگانه یا کوروتین منتقل شود، در غیر این صورت سیستم بعد از ۵ ثانیه ANR صدا میزند.
IntentService — یک وارث Service است که به طور خودکار یک ترافت کاری ایجاد و دستورات را به طور متوالی پردازش میکند. پس از اتمام آخرین وظیفه، IntentService خودکار متوقف میشود. از Android 8، IntentService در حال منسوخی در حال به نفع JobIntentService یا WorkManager است.
راهاندازی Started Service از پسزمینه در Android 12 ممنوع است. استثنا — Foreground Service با foregroundServiceType اعلام شده در مانیفست و اعلان معتبر. همچنین شروع کوتاه پس از دریافت پیام FCM با اولویت بالا مجاز است.
سه راه وجود دارد: BroadcastReceiver با broadcast محلی، مکانیزم Messenger از طریق Handler، و LiveData/Flow در معماری MVVM با ViewModel مشترک. برای Bound Service از IBinder با فراخوانی مستقیم روشها استفاده میشود.
اگر Service با پرچم START_STICKY راهاندازی شده باشد، سیستم پس از نابودی فرآیند به دلیل کمبود حافظه، آن را مجدداً راهاندازی میکند. پرچم START_NOT_STICKY به این معنی است که سیستم سرویس را مجدداً راهاندازی نمیکند. START_REDELIVER_INTENT مانند START_STICKY است اما آخرین Intent را منتقل میکند.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید