Background Service هو مكون Android مصمم لتنفيذ عمليات طويلة في الخلفية بدون واجهة مستخدم. على عكس Activity، يستمر Service في العمل حتى بعد تصغير التطبيق أو تحويل المستخدم إلى تطبيق آخر. وفقًا لـ Android Developers, 2026، يوجد ثلاثة أنواع من الخدمات: Started Service، Bound Service و Foreground Service، كل منها له دورة حياة ونطاق استخدام خاص.
النقاط الرئيسية
Background Service (أو ببساطة Service) هو أحد المكونات الأساسية الأربعة لتطبيق Android، إلى جانب Activity، BroadcastReceiver و ContentProvider. على عكس Activity، ليس لـ Service واجهة مرئية وهو مصمم لتنفيذ عمليات تجب أن تستمر بغض النظر عن وجود التطبيق في المقدمة أم لا.
Service يعمل على الخيط الرئيسي للتطبيق، لذا فإن أي عمليات حاجزة داخله تتطلب إنشاء خيط منفصل. وإذا لم يتم ذلك، سيطرح النظام 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)، قدمت Google قيودًا صارمة على الخدمات الخلفية. يسمح بتشغيل الخدمات في الخلفية (عندما لا يكون التطبيق في المقدمة) فقط في حالات اسثنائية: عند استلام إشعار دفع، بعد تمهيد الجهاز، أو عبر JobScheduler.
للمهام الطويلة التي لا تتطلب تنفيذًا فوريًا، يوصى باستخدام WorkManager أو JobScheduler. إذا كان التطبيق يحتاج حقًا إلى خدمة عاملة، الطريق الوحيد هو Foreground Service مع إشعار يراه المستخدم. سيتم تجاهل تشغيل خدمة بدون إشعار في الخلفية من قبل النظام.
JobIntentService هو فئة متخصصة ظهرت في مكتبة الدعم للعمل على 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. يوصى باستخدام WeakReference، ViewModel أو LiveData للاتصال بين Service و UI. في 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+) والإذن. لـ Bound Service، تحتاج أيضًا إلى تصريح android:permission="android.permission.BIND_JOB_SERVICE" لـ JobIntentService. بدون التسجيل في البيان، أي استدعاء لـ startService أو bindService سيؤدي إلى استثناء، لذا فإن فحص البيان هو الخطوة الأولى عند تشخيص المشاكل المتعلقة بـ Service.
الأسئلة الشائعة
Service يتم تنفيذه على الخيط الرئيسي (UI Thread) للتطبيق. أي عملية حاجزة داخل onStartCommand أو onHandleIntent يجب أن تنقل إلى خيط منفصل أو كوروتين، وإلا سيطرح النظام ANR بعد 5 ثوان.
IntentService هو فئة فرعية من Service تقوم تلقائيًا بإنشاء خيط عمل ومعالجة الأوامر بالتسلسل. بعد اكتمال آخر مهمة، يتوقف IntentService نفسه. بدءًا من Android 8، يعتبر IntentService مهملًا لصالح JobIntentService أو WorkManager.
تشغيل Started Service من الخلفية على Android 12 محظور. الاستثناء هو Foreground Service مع foregroundServiceType مصرح به في البيان وإشعار صالح. كما يسمح بتشغيل قصير بعد استلام رسالة FCM عالية الأولوية.
هناك ثلاث طرق: BroadcastReceiver مع البث المحلي، آلية Messenger عبر Handler، و LiveData/Flow في هندسة MVVM مع ViewModel مشترك. لـ Bound Service، يتم استخدام IBinder مع استدعاءات مباشرة للطرق.
إذا تم تشغيل Service بعلامة START_STICKY، سيعيد النظام تشغيله بعد إنهاء العملية بسبب نقص الذاكرة. علامة START_NOT_STICKY تعني أن النظام لن يعيد تشغيل الخدمة. START_REDELIVER_INTENT مشابه لـ START_STICKY ولكنه يقوم بتسليم آخر Intent.
الملخص
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.
اقرأ أيضًا