نظرة عامة على المهام التي يتم إجراؤها في الخلفية

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

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

المصطلحات

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

هل هي مهمة قصيرة ومهمة؟

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

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

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

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

المهام استجابةً لحدث

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

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

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

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

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

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