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

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

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

المصطلحات

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

تتوفّر طريقتان لإنشاء خدمة تعمل في المقدّمة. يمكنك تقديم بيان عن Service الخاص بك وتحديد أنّ الخدمة هي خدمة تعمل في المقدّمة من خلال الاتصال Service.startForeground(). وكحل بديل، يمكنك استخدام WorkManager لإنشاء خدمة تعمل في المقدّمة، كما هو موضّح في مقالة إتاحة استخدام العمال الذين يستغرقون وقتًا طويلاً. ومع ذلك، من المهم معرفة أنّ الخدمة التي تعمل في المقدّمة والتي أنشأها WorkManager повиннаتتقيّد بكل القيود نفسها التي تنطبق على أي خدمة أخرى تعمل في المقدّمة. لا يوفّر WorkManager سوى بعض واجهات برمجة التطبيقات المُسَهّلة لتسهيل إنشاء خدمة تعمل في المقدّمة.

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

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

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

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

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

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

هل يجب مواصلة تنفيذ المهمة عندما يكون التطبيق في الخلفية؟

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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