Background: أساسيات، عمل التطبيق في الخلفية على iOS وAndroid

المؤلف: IT Sectr نُشر: 2026-03-03 وقت القراءة: 10 دق

Background هي حالة من دورة حياة التطبيق حيث يستمر في العمل ولكن لا يظهر على الشاشة. نشرح أساسيات العمل في الخلفية على iOS وAndroid: القيود، المهلات، المهام الخلفية عبر beginBackgroundTask وWorkManager وService، بالإضافة إلى أفضل الممارسات للتعامل الصحيح مع Background.

الخلاصة

  • Background — التطبيق غير مرئي للمستخدم ولكن يمكنه تنفيذ التعليمات البرمجية لفترة محدودة
  • مهمة خلفية iOS — beginBackgroundTask(expirationHandler:) تمنح حتى 30 ثانية لإنهاء العمل
  • Android Service — Foreground Service مع إشعار للعمليات الخلفية الطويلة
  • WorkManager — API موصى بها للمهام الخلفية على Android مع ضمان التنفيذ
  • القيود — تشدد كلتا المنصتين قواعد العمل الخلفي لتوفير البطارية

Background — أساسيات حالة الخلفية

Background هي حالة التطبيق حيث يستمر في الوجود في نظام التشغيل، وينفذ التعليمات البرمجية ويستهلك الموارد، ولكن لا يظهر على شاشة الجهاز. المستخدم على الشاشة الرئيسية، أو في تطبيق آخر، أو شاشة الجهاز مقفلة. على iOS، Background يتبع Inactive — سلسلة الانتقال: Active → Inactive → Background. على Android، تشير onStop إلى انتقال النشاط إلى Background.

تفرض كلتا المنصتين قيوداً صارمة على العمل الخلفي. توفر iOS نافذة محدودة (عادة 30 ثانية) لتنفيذ التعليمات البرمجية بعد الدخول إلى Background، وبعدها ينتقل التطبيق إلى Suspended. Android أكثر مرونة: يمكن لـ Foreground Service مع إشعار مرئي العمل إلى أجل غير مسمى، لكن Background Service العادي محدود ببضع دقائق. المهمة الرئيسية للمطور هي حفظ الحالة بشكل صحيح وجدولة استمرار العمل عبر واجهات برمجة تطبيقات المهام الخلفية للنظام.

قد ينهي النظام التطبيق الخلفي في أي وقت عند انخفاض الذاكرة. عند الإنهاء، تفقد جميع البيانات غير المحفوظة. لذلك من المهم جداً حفظ الحالة في applicationDidEnterBackground (iOS) أو onStop (Android). بعد الإنهاء، يبدأ التشغيل التالي من NotRunning ببدء بارد ويستعيد الحالة المحفوظة.

Background مقابل Suspended

من المهم التمييز بين Background وSuspended. Background — التطبيق ينفذ التعليمات البرمجية بنشاط. Suspended — التطبيق في الذاكرة لكنه لا ينفذ التعليمات البرمجية — إنه مجمد. على iOS، ينتقل التطبيق من Background إلى Suspended بعد إكمال المهام الخلفية. Android ليس لديه Suspended — العملية إما موجودة (بما في ذلك Background) أو منتهية (Not Running). ومع ذلك، يمكن لـ Android إيقاف تنفيذ الخيوط مؤقتاً عبر LMK (Low Memory Killer).

الخاصيةiOS BackgroundAndroid Background
تنفيذ التعليمات البرمجيةنعم، حتى 30 ثانيةنعم، يعتمد على API
واجهة المستخدم مرئيةلالا
المهلة الافتراضية~30 ثانية (beginBackgroundTask)عدة دقائق (Service)
عمل غير محدودفئات خاصة فقط (الصوت، VoIP، الملاحة)Foreground Service مع إشعار
ضمان التنفيذلا — قد ينهي النظام في أي وقتWorkManager يضمن التنفيذ
يتطلب إذناًنعم — capabilities في Info.plistنعم — إذن FOREGROUND_SERVICE
الحالة التاليةSuspended → Not RunningNot Running (أو إعادة تشغيل)

Background على iOS: Swift وbeginBackgroundTask وBGTaskScheduler

على iOS، تتم معالجة Background من خلال طريقة المفوض applicationDidEnterBackground. في هذه الطريقة، يجب على المطور حفظ حالة المستخدم، تحرير الموارد، وإكمال المهام الخلفية. لتنفيذ التعليمات البرمجية بعد الدخول إلى Background، يتم استخدام beginBackgroundTask(expirationHandler:) — وهي API تطلب وقتاً إضافياً من النظام (عادة 30 ثانية). إذا لم تكتمل المهمة خلال هذا الوقت، يتم استدعاء expirationHandler، ويتم نقل التطبيق قسراً إلى Suspended.

مع iOS 13، قدمت Apple BGTaskScheduler — وهي API حديثة لجدولة المهام الخلفية. على عكس beginBackgroundTask الذي يعطي وقتاً فقط للإنهاء بعد الذهاب إلى الخلفية، يسمح BGTaskScheduler بجدولة تنفيذ المهام في المستقبل — على سبيل المثال، تحديث المحتوى مرة كل ساعة أو رفع التحليلات ليلاً. BGTaskScheduler هو النهج الموصى به للمشاريع الجديدة، حيث أنه أكثر كفاءة في استهلاك البطارية.

swift
import UIKit
import BackgroundTasks

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    var backgroundTaskID: UIBackgroundTaskIdentifier = .invalid

    // التطبيق ذهب إلى الخلفية — بدء مهمة خلفية
    func applicationDidEnterBackground(_ application: UIApplication) {
        saveAppState()
        startBackgroundTask()
    }

    private func startBackgroundTask() {
        backgroundTaskID = UIApplication.shared.beginBackgroundTask { [weak self] in
            // انتهى الوقت — إنهاء قسري
            self?.endBackgroundTask()
        }

        // محاكاة العمل الخلفي (حفظ البيانات على الخادم)
        DispatchQueue.global().async { [weak self] in
            uploadAnalyticsData()
            self?.endBackgroundTask()
        }
    }

    private func endBackgroundTask() {
        guard backgroundTaskID != .invalid else { return }
        UIApplication.shared.endBackgroundTask(backgroundTaskID)
        backgroundTaskID = .invalid
    }

    // تسجيل BGTaskScheduler
    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        BGTaskScheduler.shared.register(
            forTaskWithIdentifier: "com.example.refresh",
            using: nil
        ) { task in
            handleAppRefresh(task: task as! BGAppRefreshTask)
        }
        return true
    }

    func scheduleAppRefresh() {
        let request = BGAppRefreshTaskRequest(identifier: "com.example.refresh")
        request.earliestBeginDate = Date(timeIntervalSinceNow: 3600)
        try? BGTaskScheduler.shared.submit(request)
    }

    func handleAppRefresh(task: BGAppRefreshTask) {
        scheduleAppRefresh()
        task.expirationHandler = { task.setTaskCompleted(success: false) }
        fetchLatestData { result in
            task.setTaskCompleted(success: result)
        }
    }
}

يظهر الكود معالجة كاملة لـ Background على iOS. applicationDidEnterBackground يبدأ مهمة خلفية عبر beginBackgroundTask مع مهلة وexpirationHandler. في نفس الوقت، يتم تسجيل BGTaskScheduler للتحديثات الدورية للمحتوى. يُستخدم beginBackgroundTask لمهام الإنهاء الفوري، وBGTaskScheduler للتخطيط طويل المدى. تتطلب كلتا API إدارة صحيحة لمعرفات المهام.

Background على Android: Kotlin وService وWorkManager

على Android، تتم إدارة Background من خلال عدة APIs. يسمح Service التقليدي بتنفيذ التعليمات البرمجية في الخلفية، لكن منذ Android 8+ (API 26)، أصبح Background Service محدوداً: ينهيه النظام بعد بضع دقائق من ذهاب التطبيق إلى الخلفية. يمكن لـ Foreground Service مع إشعار دائم العمل إلى أجل غير مسمى. WorkManager هو الحل الموصى به للمهام الخلفية مع ضمان التنفيذ حتى بعد إعادة تشغيل الجهاز.

Android، على عكس iOS، يدعم العمليات الخلفية طويلة الأمد. يُستخدم Foreground Service للمهام التي يجب أن يراها المستخدم — تشغيل الموسيقى، الملاحة، تتبع التمارين. يُستخدمان JobScheduler وWorkManager للمهام التي يمكن تأجيلها: مزامنة البيانات، رفع السجلات، تحديث الذاكرة المؤقتة. الفرق الرئيسي: يسمح Android بجدولة المهام مع شروط — Wi-Fi، الشحن، خمول الجهاز — مما يوفر البطارية وحركة المرور.

kotlin
import android.app.Service
import android.content.Intent
import android.os.IBinder
import androidx.work.*

// 1. Foreground Service للعمل الخلفي الطويل
class SyncService : Service() {

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        val notification = createNotification()
        startForeground(NOTIFICATION_ID, notification)
        performBackgroundWork()
        return START_STICKY
    }

    private fun performBackgroundWork() {
        Thread {
            // مزامنة البيانات مع الخادم
            syncDataToServer()
            stopForeground(STOP_FOREGROUND_REMOVE)
            stopSelf()
        }.start()
    }

    override fun onBind(intent: Intent?): IBinder? = null
}

// 2. WorkManager للمهام الخلفية المؤجلة
class DataSyncWorker(
    private val context: Context,
    private val params: WorkerParameters
) : CoroutineWorker(context, params) {

    override suspend fun doWork(): Result {
        return try {
            // رفع التحليلات إلى الخادم
            uploadAnalytics()
            Result.success()
        } catch (e: Exception) {
            if (runAttemptCount < 3) Result.retry() else Result.failure()
        }
    }
}

// جدولة مهمة WorkManager
fun scheduleBackgroundSync(context: Context) {
    val constraints = Constraints.Builder()
        .setRequiredNetworkType(NetworkType.CONNECTED)
        .setRequiresBatteryNotLow(true)
        .build()

    val request = OneTimeWorkRequestBuilder<DataSyncWorker>()
        .setConstraints(constraints)
        .setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 30, TimeUnit.SECONDS)
        .build()

    WorkManager.getInstance(context).enqueue(request)
}

يظهر الكود نهجين للعمل الخلفي على Android. SyncService — Foreground Service مع إشعار للعمل الخلفي الفوري والطويل. DataSyncWorker — WorkManager للمهام المؤجلة مع شروط (Wi-Fi، الشحن). يضمن WorkManager التنفيذ حتى بعد إعادة تشغيل الجهاز ويدعم التراجع الأسي لإعادة المحاولات. يتطلب Foreground Service إشعاراً دائماً في شريط الحالة.

قيود العمل الخلفي على iOS وAndroid

كلتا المنصتين المحمولتين تشددان باستمرار قواعد العمل الخلفي. على iOS، كل جيل جديد من نظام التشغيل يقلل وقت التنفيذ في الخلفية ويضيف قيوداً جديدة. على Android، تقدم Google أوضاع توفير طاقة أكثر صرامة (Doze، App Standby). يجب على المطورين متابعة القيود الحالية لمنع إنهاء التطبيق قبل الأوان بواسطة النظام.

على iOS، بدءاً من iOS 13، يعطل النظام المهام الخلفية للتطبيقات التي تسيء استخدام الوقت الخلفي. يحصل كل تطبيق على حدود معينة بناءً على سلوك المستخدم. BGTaskScheduler يجدول التنفيذ في الأوقات المثلى — على سبيل المثال، عندما يكون الجهاز متصلاً بـ Wi-Fi ويشحن. التطبيقات التي تستخدم BGTaskScheduler بشكل صحيح تحصل على وقت خلفي أكثر.

على Android، بدءاً من Android 9 (API 28)، العمل الخلفي مقيد بوضع Doze، الذي ينشط عندما يكون الجهاز خاملاً. لا يمكن للتطبيقات في Doze تنفيذ مهام خلفية، يتم فصل الشبكة، ويؤجل JobScheduler وWorkManager المهام حتى الخروج من Doze. Foreground Service هو الطريقة الوحيدة لتجاوز Doze، لكن إساءة الاستخدام تؤدي إلى حظر التطبيق من قبل المستخدم وإلغاء الأذونات.

القيودiOSAndroid
مهلة المهمة الخلفية~30 ثانية (beginBackgroundTask)عدة دقائق (JobScheduler)
خلفية غير محدودةالصوت، VoIP، الملاحة، BluetoothForeground Service + إشعار
توفير الطاقةوضع الطاقة المنخفضة — يعطل المهام الخلفيةDoze، App Standby، تحسين البطارية
الجدولةBGTaskScheduler (iOS 13+)WorkManager (Android Jetpack)
بعد إعادة التشغيلإشعار push فقطWorkManager يحتفظ بالمهام
الحد الأقصى لوقت التنفيذ~30 دقيقة (الصوت)غير محدود (Foreground Service)

أفضل الممارسات للعمل الخلفي

القاعدة الأولى — قلل استهلاك الموارد في الخلفية. يمكن تأجيل معظم المهام الخلفية إلى وقت شحن الجهاز واتصاله بـ Wi-Fi. استخدم BGTaskScheduler (iOS) وWorkManager (Android) لجدولة المهام مع شروط. لا تقم بتشغيل حسابات ثقيلة في الخلفية — هذا يستنزف البطارية ويؤدي إلى خفض أداء المعالج.

القاعدة الثانية — حدد دائماً expirationHandler لـ beginBackgroundTask. إذا لم يكمل التطبيق المهمة في الوقت المخصص، سينقله النظام قسراً إلى Suspended أو ينهيه. expirationHandler هي الفرصة الأخيرة لحفظ البيانات وإنهاء العمل بشكل صحيح. على Android، استخدم setForegroundAsync في WorkManager لتحويل مهمة عادية إلى مقدمة إذا كان هناك حاجة لمزيد من الوقت.

القاعدة الثالثة — تحقق من قيود العمل الخلفي قبل التشغيل. على iOS، استخدم UIApplication.shared.backgroundTimeRemaining للتحقق من الوقت المتبقي. على Android، تحقق من ActivityManager.isBackgroundRestricted() — إذا كان true، لا يمكن للتطبيق تشغيل المهام الخلفية، ويجب اقتراح إزالة القيود في الإعدادات. هذا مهم بشكل خاص للتطبيقات ذات الوظائف الخلفية الحرجة — المنبهات، التقاويم، المزامنة.

القاعدة الرابعة — اختبر المهام الخلفية على جهاز حقيقي. لا تحاكي أجهزة المحاكاة القيود الحقيقية للعمل الخلفي. على iOS، استخدم Debug → Simulate Background Fetch في Xcode. على Android، استخدم adb shell am broadcast -a android.intent.action.ACTION_BOOT_COMPLETED لاختبار WorkManager بعد إعادة التشغيل. الاختبارات الحقيقية على جهاز ببطارية منخفضة تكشف معظم مشاكل العمل الخلفي.

swift
import UIKit

final class BackgroundTaskManager {
    static let shared = BackgroundTaskManager()
    private var tasks: [String: UIBackgroundTaskIdentifier] = [:]

    func startTask(name: String, expiration: @escaping () -> Void) {
        let remaining = UIApplication.shared.backgroundTimeRemaining
        print("الوقت المتبقي في الخلفية: \(remaining) ثانية")

        let task = UIApplication.shared.beginBackgroundTask { [weak self] in
            print("انتهى الوقت للمهمة: \(name)")
            expiration()
            self?.endTask(name: name)
        }

        tasks[name] = task
    }

    func endTask(name: String) {
        guard let task = tasks.removeValue(forKey: name),
              task != .invalid
        else { return }
        UIApplication.shared.endBackgroundTask(task)
    }
}

يظهر الكود مدير مهام خلفية يتتبع الوقت المتبقي ويدير المعرفات. backgroundTimeRemaining يعيد عدد الثواني قبل الإنهاء القسري — إذا كانت القيمة لا نهائية، فإن التطبيق يعمل بدون قيود (صوت، ملاحة). يسمح المدير بتشغيل مهام خلفية متعددة بأسماء مختلفة وإكمال كل منها بشكل صحيح. هذا النهج يمنع تسرب المهام الخلفية ويضمن أن النظام لن ينهي التطبيق بسبب مهام غير مغلقة.

الأسئلة الشائعة

هل يمكن لتطبيق iOS العمل في الخلفية إلى الأبد؟

نعم، لعدد محدود من الفئات: الصوت (AVAudioSession فئة .playback)، VoIP (PushKit)، الملاحة (CLLocationManager مع allowsBackgroundLocationUpdates)، Bluetooth (وضع الخلفية المركزي)، التحديث الخلفي (BGTaskScheduler). لكل الآخرين — حد أقصى 30 ثانية. في iOS 16+، شددت Apple المتطلبات حتى للفئات المسموح بها.

كيف يختلف beginBackgroundTask عن BGTaskScheduler؟

beginBackgroundTask هي API متزامنة لتمديد عمر التطبيق ~30 ثانية بعد الذهاب إلى الخلفية. يتم استدعاؤها في applicationDidEnterBackground. BGTaskScheduler هي API غير متزامنة لجدولة المهام في المستقبل عبر مشغلات النظام (الوقت، الموقع، تحديث المحتوى). BGTaskScheduler هو النهج الحديث الموصى به من Apple لـ iOS 13+.

لماذا يقتل Android خدمة الخلفية الخاصة بي؟

بدءاً من Android 8 (API 26)، يتم إنهاء Background Service بعد بضع دقائق من ذهاب التطبيق إلى الخلفية. الحل: استخدم Foreground Service مع إشعار للعمليات الطويلة أو WorkManager للمهام المؤجلة. تحقق من تحسين البطارية لتطبيقك في الإعدادات — إذا كان محسّناً، قد يؤجل النظام أو يلغي المهام الخلفية.

كيف أختبر Background على محاكي iOS؟

اضغط Cmd+Shift+H للذهاب إلى الشاشة الرئيسية. في Xcode، استخدم Debug → Simulate Background Fetch. للتحقق من beginBackgroundTask، افتح وحدة التحكم (Shift+Cmd+C) واستدع e UIApplication.shared.backgroundTimeRemaining. في Xcode 15+، يتوفر سيناريو Background Execution في علامة Diagnostics في المحاكي.

ما هو process death على Android؟

Process Death هو إنهاء عملية Android بواسطة النظام عند انخفاض الموارد أو عند الخمول في الخلفية. على عكس iOS، Android ليس لديه Suspended — العملية إما حية (يمكن أن تكون في الخلفية) أو ميتة (Not Running). Process Death هو سلوك طبيعي لنظام التشغيل، ويجب على التطبيق استعادة الحالة بشكل صحيح بعده عبر SavedStateHandle أو onSaveInstanceState أو DataStore.

الملخص

  • Background — التطبيق غير مرئي على الشاشة لكنه ينفذ التعليمات البرمجية، على عكس Suspended (مجمد)
  • iOS — beginBackgroundTask (حتى 30 ثانية) وBGTaskScheduler لجدولة المهام المستقبلية
  • Android — Foreground Service للعمليات الطويلة، WorkManager للمهام المؤجلة مع ضمان
  • القيود — كلتا المنصتين تشددان قواعد العمل الخلفي: Doze، Low Power Mode، App Standby
  • الحفظ — applicationDidEnterBackground وonStop هما الفرصة الأخيرة قبل Suspended/Not Running
  • الجدولة — BGTaskScheduler وWorkManager يعملان مع شروط (Wi-Fi، الشحن، الوقت)
  • Foreground Service — الطريقة الوحيدة للعمل الخلفي غير المحدود على كلتا المنصتين

سنقوم بتطوير تطبيق جوال جاهز

تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.

مناقشة المشروع

اقرأ أيضًا