نظرة عامة على العمل في الخلفية

تحتاج التطبيقات إلى تنفيذ أكثر من إجراء واحد في كل مرة. وتوفر واجهات برمجة تطبيقات Android العديد من الطرق المختلفة التي تتيح لك ذلك. يُعدّ تحديد الخيار الصحيح أمرًا مهمًا للغاية، فقد يكون الخيار مناسبًا لموقف معيّن ولكنه خاطئ جدًا بالنسبة إلى موقف آخر. قد يؤدي اختيار واجهات برمجة التطبيقات الخاطئة إلى الإضرار بأداء تطبيقك أو كفاءة موارده، مما قد يستنزف طاقة البطارية وتدهور أداء جهاز المستخدم كبشكلٍ عام. في بعض الحالات، قد يؤدي اختيار المنهج الخاطئ إلى منع إدراج تطبيقك في متجر Play.

يشرح هذا المستند الخيارات المختلفة المتاحة لك ويساعدك على اختيار الخيار المناسب لموقفك.

المصطلحات

قد يتم استخدام بعض المصطلحات المهمة المتعلقة بالعمل في الخلفية بطرق متعددة ومتناقضة. ولهذا السبب، من المهم تعريف هذه المصطلحات.

إذا كان التطبيق يعمل في الخلفية، فإن النظام يضع عليه عددًا من القيود. (على سبيل المثال، في معظم الحالات، لا يمكن لتطبيق يعمل في الخلفية تشغيل الخدمات التي تعمل في المقدّمة.)

لأغراض هذا المستند، سنستخدم مصطلح "مهمة" للإشارة إلى عملية يقوم بها التطبيق خارج سير العمل الرئيسي. لضمان المواءمة في الفهم، وضعنا ذلك ضمن ثلاث فئات رئيسية من أنواع المهام: العمل غير المتزامن والعمل في الخلفية والخدمات التي تعمل في المقدّمة.

تحديد الخيار المناسب

في معظم السيناريوهات، يمكنك اكتشاف واجهات برمجة التطبيقات المناسبة لاستخدامها في مهمتك من خلال تحديد الفئة (العمل غير المتزامن أو العمل الأساسي أو الخدمات التي تعمل في المقدّمة) التي تندرج تحتها المهمة.

إذا كنت لا تزال غير متأكد، يمكنك استخدام المخططات التدفقية التي نوفرها والتي تضيف المزيد من الفروقات الدقيقة إلى القرار. يتم وصف كل خيار من هذه الخيارات بمزيد من التفصيل لاحقًا في هذا المستند.

هناك سيناريوهان رئيسيان يجب مراعاتهما للعمل في الخلفية:

هذان السيناريوهان لهما أشجار القرارات الخاصة بهما.

العمل غير المتزامن

في حالات عديدة، يحتاج التطبيق فقط إلى إجراء عمليات متزامنة أثناء تشغيله في المقدمة. على سبيل المثال، قد يحتاج أحد التطبيقات إلى إجراء عملية حسابية تستغرق وقتًا طويلاً. إذا أجرى العملية الحسابية على سلسلة واجهة المستخدم، لن يتمكن المستخدم من التفاعل مع التطبيق حتى تنتهي العملية الحسابية؛ وقد يؤدي ذلك إلى خطأ ANR. في مثل هذه الحالة، يجب أن يستخدم التطبيق خيار العمل غير المتزامن.

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

العمل في الخلفية

نجد أنّ العمل في الخلفية هو خيار أكثر مرونة عندما تحتاج إلى تنفيذ عمل يجب أن يستمر حتى بعد مغادرة المستخدم التطبيق. وفي معظم الحالات، يكون الخيار الأفضل للعمل في الخلفية هو استخدام WorkManager، ولكنّ استخدام WorkManager قد يكون مناسبًا في بعض الحالات.JobScheduler

WorkManager هي مكتبة قوية تتيح لك إعداد مهام بسيطة أو معقدة حسب حاجتك. يمكنك استخدام WorkManager لجدولة المهام لتشغيلها في أوقات محددة، أو تحديد الشروط التي يجب تشغيل المهمة فيها. يمكنك حتى إعداد سلاسل من المهام، بحيث يتم تشغيل كل مهمة تباعًا، وتمرير نتائجها إلى المهمة التالية. لفهم جميع الخيارات المتاحة، يُرجى الاطّلاع على قائمة ميزات WorkManager.

في ما يلي بعض السيناريوهات الأكثر شيوعًا للعمل في الخلفية:

  • يتم جلب البيانات من الخادم بشكل دوري
  • جارٍ استرجاع بيانات جهاز الاستشعار (مثل بيانات عدّاد الخطوات)
  • الحصول على بيانات الموقع الجغرافي الدورية (يجب أن تحصل على إذن ACCESS_BACKGROUND_LOCATION على نظام التشغيل Android 10 أو الإصدارات الأحدث)
  • تحميل المحتوى استنادًا إلى مشغِّل المحتوى، مثل الصور التي أنشأتها الكاميرا

الخدمات التي تعمل في المقدّمة

تقدم الخدمات التي تعمل في المقدمة طريقة قوية لتشغيل المهام التي يجب عدم مقاطعتها على الفور. ومع ذلك، من المحتمل أن تُحمّل الخدمات التي تعمل في المقدّمة عبئًا ثقيلًا على الجهاز، وأحيانًا يكون لها آثار على الخصوصية والأمان. ولهذه الأسباب، يضع النظام الكثير من القيود على كيفية ووقت استخدام التطبيقات للخدمات التي تعمل في المقدّمة. على سبيل المثال، يجب أن تكون الخدمة التي تعمل في المقدّمة ملحوظة للمستخدم، وفي معظم الحالات لا يمكن للتطبيقات تشغيل الخدمات التي تعمل في المقدّمة عندما تكون التطبيقات قيد التشغيل في الخلفية. لمزيد من المعلومات، راجع مستندات الخدمات التي تعمل في المقدّمة.

هناك طريقتان لإنشاء خدمة تعمل في المقدّمة. يمكنك توضيح Service الخاص بك وتوضيح أنّ الخدمة تعمل في المقدّمة من خلال طلب رمز Service.startForeground(). بدلاً من ذلك، يمكنك استخدام WorkManager لإنشاء خدمة تعمل في المقدّمة، كما هو موضّح في مقالة دعم العمال الذين يعملون لفترة طويلة. ومع ذلك، من المهم أن تعرف أنّ الخدمة التي تعمل في المقدّمة أنشأها WorkManager يجب أن تتّبع جميع القيود نفسها المفروضة على أي خدمة أخرى تعمل في المقدّمة. لا يوفّر WorkManager سوى بعض واجهات برمجة التطبيقات المناسبة لتسهيل إنشاء خدمة تعمل في المقدّمة.

واجهات برمجة التطبيقات البديلة

يوفّر النظام واجهات برمجة تطبيقات بديلة مصمّمة لتقديم أداء أفضل في حالات استخدام أكثر تحديدًا. في حال توفُّر واجهة برمجة تطبيقات بديلة لحالة الاستخدام الخاصة بك، ننصحك باستخدام واجهة برمجة التطبيقات هذه بدلاً من خدمة تعمل في المقدّمة لأنّ ذلك من المفترض أن يساعد في تحسين أداء تطبيقك. تلاحظ مستندات أنواع الخدمات التي تعمل في المقدّمة عندما يكون هناك واجهة برمجة تطبيقات بديلة جيدة لاستخدامها بدلاً من نوع معيّن من الخدمات التي تعمل في المقدّمة.

في ما يلي بعض السيناريوهات الأكثر شيوعًا لاستخدام واجهات برمجة التطبيقات البديلة:

المهام التي بدأها المستخدم

رسم بياني انسيابي يوضّح كيفية اختيار واجهة برمجة التطبيقات المناسبة يلخّص هذا الرسم البياني المواد الواردة في القسم "المهام التي بدأها المستخدم".
الشكل 1: كيفية اختيار واجهة برمجة التطبيقات المناسبة لتشغيل مهمة في الخلفية يبدأها المستخدم.

إذا كان التطبيق بحاجة إلى تنفيذ عمل في الخلفية، وبدأ المستخدم العملية عندما يكون التطبيق مرئيًا، فأجب عن هذه الأسئلة للعثور على النهج الصحيح.

هل يجب مواصلة تنفيذ المهمة أثناء تشغيل التطبيق في الخلفية؟

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

هل ستكون هناك تجربة سيئة للمستخدم إذا تم تأجيل المهمة أو مقاطعتها؟

من المهم مراعاة ما إذا كانت تجربة المستخدم لن تتأثر إذا تم تأجيل المهمة أو إلغاؤها. على سبيل المثال، إذا احتاج تطبيق إلى تحديث أصوله، فقد لا يلاحظ المستخدم ما إذا كانت العملية تحدث على الفور، أم في منتصف الليل أثناء إعادة شحن الجهاز. في مثل هذه الحالات، يجب عليك استخدام خيارات العمل في الخلفية.

هل هي مهمة قصيرة وحاسمة؟

وإذا تعذّر تأجيل المهمة وستكتمل بسرعة، يمكنك استخدام خدمة تعمل في المقدّمة بالنوع shortService. ويسهل إنشاء هذه الخدمات مقارنةً بالخدمات الأخرى التي تعمل في المقدّمة، ولا تتطلّب الكثير من الأذونات. ومع ذلك، يجب أن تكتمل الخدمات القصيرة في غضون ثلاث دقائق.

هل توجد واجهة برمجة تطبيقات بديلة لهذا الغرض فقط؟

إذا لم تكن المهمة غير مرئية للمستخدم، قد يكون الحل الصحيح هو استخدام خدمة تعمل في المقدّمة. تعمل هذه الخدمات بشكل مستمر بعد أن بدأت، لذا فهي اختيار جيد، فعندما يؤدي إيقاف المهمة إلى ترك انطباع سيئ لدى المستخدم. على سبيل المثال، قد يستخدم تطبيق تتبُّع التمارين أجهزة استشعار الموقع الجغرافي للسماح للمستخدمين بتسجيل مسار الركض على الخريطة. لن ترغب في القيام بذلك باستخدام خيار العمل في الخلفية، لأنه إذا تم إيقاف المهمة مؤقتًا، فسيتوقف التتبع على الفور. في مثل هذه الحالة، تكون الخدمة التي تعمل في المقدّمة أكثر منطقية.

ومع ذلك، ولأن الخدمات التي تعمل في المقدّمة يمكن أن تستخدم الكثير من موارد الجهاز، يضع النظام الكثير من القيود على وقت وكيفية استخدامها. في كثير من الحالات، بدلاً من استخدام خدمة تعمل في المقدّمة، يمكنك استخدام واجهة برمجة تطبيقات بديلة لتتولى هذه المهمة نيابةً عنك بطريقة أقل تعقيدًا. على سبيل المثال، إذا كان تطبيقك يحتاج إلى اتخاذ إجراء عند وصول المستخدم إلى موقع جغرافي معيّن، يكون الخيار الأفضل هو استخدام geofence API بدلاً من تتبُّع الموقع الجغرافي للمستخدم من خلال خدمة تعمل في المقدّمة.

المهام ردًا على حدث

رسم بياني انسيابي يوضّح كيفية اختيار واجهة برمجة التطبيقات المناسبة يلخّص هذا الرسم البياني المواد الواردة في القسم "المهام استجابةً لحدث ما".
الشكل 2: كيفية اختيار واجهة برمجة التطبيقات المناسبة لتشغيل مهمة في الخلفية يتم تشغيلها بحدث.

في بعض الأحيان، يحتاج أحد التطبيقات إلى تنفيذ أعمال في الخلفية استجابة لأحد العوامل، مثل:

قد يكون هذا مشغّلاً خارجيًا (مثل رسالة FCM)، أو قد يكون استجابة لمنبّه تم ضبطه في التطبيق نفسه. على سبيل المثال، قد تتلقّى اللعبة رسالة "المراسلة عبر السحابة الإلكترونية من Firebase" تخبرها بتعديل بعض مواد العرض.

إذا كنت متأكدًا من أن المهمة ستنتهي في بضع ثوانٍ، استخدِم العمل غير المتزامن لتنفيذ المهمة. سيسمح النظام لتطبيقك ببضع ثوانٍ لتنفيذ أي من هذه المهام، حتى لو كان تطبيقك في الخلفية.

إذا كانت المهمة ستستغرق وقتًا أطول من بضع ثوانٍ، قد يكون من المناسب بدء خدمة تعمل في المقدّمة لمعالجة المهمة. في الواقع، حتى إذا كان تطبيقك في الخلفية حاليًا، قد يُسمح له ببدء خدمة تعمل في المقدّمة إذا بدأ المستخدم المهمة وكانت تندرج ضمن أحد الاستثناءات من القيود المفروضة على بدء التشغيل في الخلفية التي تمت الموافقة عليها. على سبيل المثال، إذا تلقّى التطبيق رسالة ذات أولوية عالية من خدمة "المراسلة عبر السحابة الإلكترونية من Firebase"، يُسمح للتطبيق ببدء خدمة تعمل في المقدّمة حتى إذا كان التطبيق يعمل في الخلفية.

وإذا استغرقت المهمة أكثر من بضع ثوانٍ، استخدِم العمل في الخلفية.