في معظم الحالات، يتم تشغيل كل تطبيق Android في عملية Linux خاصة به. يتم إنشاء هذه العملية للتطبيق عندما يحتاج بعض رمزه إلى التشغيل ويظلّ قيد التشغيل إلى أن يحتاج النظام إلى استرداد ذاكرته لاستخدامه من قِبل التطبيقات الأخرى، وعندما لا يعود مطلوبًا.
من الميزات غير المعتادة والأساسية في نظام التشغيل Android أنّه لا يتحكّم التطبيق نفسه مباشرةً في مدّة حياة عملية التطبيق. بدلاً من ذلك، يحدّد النظام هذه القيمة من خلال مجموعة من أجزاء التطبيق التي يعرف النظام أنّها قيد التشغيل، ومدى أهمية هذه الأجزاء للمستخدم، وإجمالي سعة الذاكرة المتاحة في النظام.
من المهم أن يعرف مطوّرو التطبيقات كيفية تأثير مكوّنات التطبيق المختلفة (ولا سيما Activity
وService
وBroadcastReceiver
) في مدّة
عملية التطبيق. يمكن أن يؤدي عدم استخدام هذه المكوّنات بشكلٍ صحيح
إلى إيقاف النظام لمعالجة التطبيق أثناء تنفيذه
عملاً مهمًا.
من الأمثلة الشائعة على أخطاء دورة حياة العملية هو
BroadcastReceiver
الذي يبدأ سلسلة محادثات عند
تلقّي Intent
في BroadcastReceiver.onReceive()
الطريقة ثم يعود من الدالة. بعد عودته، يصنّف النظامBroadcastReceiver
على أنّه لم يعُد نشطًا، وأنّ عملية استضافته لم تعُد مطلوبة، ما لم تكن مكوّنات التطبيق الأخرى نشطة فيه.
وبالتالي، يمكن للنظام إنهاء العملية في أي وقت لاسترداد الذاكرة، وعند إجراء ذلك،
يُنهي النظام سلسلة المهام التي تم إنشاؤها أثناء العملية. عادةً ما يكون حلّ هذه المشكلة هو تحديد موعد JobService
من BroadcastReceiver
حتى يعرف
النظام أنّ هناك عملًا نشطًا في هذه العملية.
لتحديد العمليات التي يجب إغلاقها عند انخفاض سعة الذاكرة، يصنِّف Android كل عملية في تسلسل هرمي للأهمية استنادًا إلى المكوّنات التي تعمل في هذه العمليات وحالتها. حسب الأهمية، أنواع العمليات هذه هي:
- العملية التي تعمل في المقدّمة هي عملية مطلوبة للقيام بنشاط المستخدم الحالي. يمكن أن تؤدي مكوّنات التطبيق المختلفة إلى اعتبار العملية التي تحتويها في المقدّمة بطرق مختلفة. تُعتبر العملية قيد الاستخدام في المقدّمة إذا كان أيّ من
الشروط التالية ساريًا:
- يتم تشغيل
Activity
في أعلى الشاشة التي يتفاعل معها المستخدم (تمّت دعوةonResume()
). - يحتوي على
BroadcastReceiver
قيد التشغيل حاليًا (يتم تنفيذ طريقةBroadcastReceiver.onReceive()
). - يحتوي على
Service
ينفذ حاليًا رمزًابرمجيًا في إحدى وظائف الاستدعاء (Service.onCreate()
أوService.onStart()
أوService.onDestroy()
).
- يتم تشغيل
- تُجري العملية المرئية عملية يدركها المستخدم حاليًا،
لذلك سيؤدّي إغلاقها إلى تأثير سلبي ملحوظ في تجربة المستخدم. تُعدّ العملية
مرئية في الحالات التالية:
- يتم تشغيل
Activity
يظهر للمستخدم على الشاشة ولكن ليس في المقدّمة (تمّت دعوةonPause()
method ). قد يحدث ذلك مثلاً إذا تم عرضActivity
في المقدّمة على شكل مربّع حوار يتيح رؤيةActivity
السابق من خلاله. - يحتوي على
Service
يعمل كخدمة تعمل في المقدّمة، من خلالService.startForeground()
(الذي يطلب من النظام التعامل مع الخدمة على أنّها شيء يعلم به المستخدم، أو كما لو كانت مرئية). - يستضيف التطبيق خدمة يستخدمها النظام لميزة معيّنة يعرفها المستخدم، مثل خلفية حية أو خدمة أسلوب إدخال.
إنّ عدد هذه العمليات التي تعمل في النظام أقل تقييدًا من العمليات التي تعمل في المقدّمة، ولكن لا يزال يتم التحكّم فيها نسبيًا. تُعدّ هذه العمليات مهمة للغاية ولا يتم إيقافها إلا إذا كان ذلك مطلوبًا لإبقاء جميع العمليات التي تعمل في المقدّمة قيد التشغيل.
- يتم تشغيل
- عملية الخدمة هي عملية تمتلك
Service
تم بدء تشغيلها باستخدام الأسلوبstartService()
. على الرغم من أنّه لا يمكن للمستخدم رؤية هذه العمليات مباشرةً، إلا أنّها تُجري بشكل عام إجراءات تهمّه (مثل تحميل أو تنزيل بيانات الشبكة في الخلفية)، لذلك يحافظ النظام دائمًا على تشغيل هذه العمليات ما لم تكن الذاكرة غير كافية للاحتفاظ بجميع العمليات التي تعمل في المقدّمة والعمليات المرئية.قد يتم خفض شأن الخدمات التي تعمل منذ فترة طويلة (مثل 30 دقيقة أو أكثر) لإدراجها في القائمة المخزّنة مؤقتًا.
يمكن إنشاء العمليات التي يجب تنفيذها على مدار فترة طويلة باستخدام
setForeground
. إذا كانت عملية دورية تتطلّب وقت تنفيذ صارمًا، يمكن تحديد موعد لها من خلالAlarmManager
. لمزيد من المعلومات، يُرجى الاطّلاع على مقالة التوافق مع عمليات التشغيل التي تستغرق وقتًا طويلاً. يساعد ذلك في تجنُّب المواقف التي تمنع فيها الخدمات التي تعمل لفترة طويلة وتستخدم موارد زائدة، مثلاً، من خلال تسرُّب الذاكرة، النظام من تقديم تجربة مستخدم جيدة. - العملية المخزّنة مؤقتًا هي عملية غير مطلوبة حاليًا، لذا
يمكن للنظام إغلاقها حسب الحاجة عندما تكون هناك حاجة إلى موارد مثل الذاكرة في مكان آخر. في النظام الذي يعمل بشكلٍ طبيعي، هذه هي العمليات الوحيدة المشارِكة في إدارة الموارد.
يتضمّن النظام الذي يعمل بكفاءة عمليات متعددة محفوظة في ذاكرة التخزين المؤقت متاحة دائمًا، وذلك للتبديل بكفاءة بين التطبيقات، ويوقف بانتظام التطبيقات المحفوظة في ذاكرة التخزين المؤقت حسب الحاجة. لا يصل النظام إلى نقطة يتم فيها إغلاق جميع العمليات المخزّنة مؤقتًا إلا في الحالات الحرجة جدًا، ويجب أن يبدأ بإغلاق عمليات الخدمات.
بما أنّ النظام يمكنه إنهاء العمليات المخزّنة مؤقتًا في أي وقت، يجب أن تتوقف التطبيقات عن العمل بالكامل عندما تكون في هذه الحالة. إذا كان على التطبيق تنفيذ عمل مهم للمستخدم، يجب أن يستخدم إحدى واجهات برمجة التطبيقات المذكورة أعلاه لتنفيذ العمل من حالة عملية نشطة.
غالبًا ما تحتوي العمليات المخزّنة مؤقتًا على مثيل واحد أو أكثر من
Activity
غير المرئي حاليًا للمستخدم (تمّت دعوةonStop()
method وعادت). شرط أن يتم تنفيذ دورة حياةActivity
بشكل صحيح عندما يُغلق النظام هذه العمليات، لن يؤثر ذلك في تجربة المستخدم عند العودة إلى هذا التطبيق. يمكنه استعادة الحالة المحفوظة سابقًا عند إعادة إنشاء النشاط المرتبط في عملية جديدة. يُرجى العِلم أنّه لا يمكن ضمان استدعاءonDestroy()
في حال أوقف النظام إحدى العمليات. لمزيد من التفاصيل، يُرجى الاطّلاع علىActivity
.بدءًا من Android 13، قد تحصل عملية التطبيق على وقت تنفيذ محدود أو لا تحصل على أي وقت تنفيذ إلى أن تدخل إحدى حالات دورة الحياة النشطة أعلاه.
يتم الاحتفاظ بالعمليات المخزّنة مؤقتًا في قائمة. إنّ سياسة الترتيب الدقيقة لهذه القائمة هي من تفاصيل تنفيذ المنصة. بشكل عام، يحاول النظام إبقاء العمليات الأكثر فائدة، مثل تلك التي تستضيف تطبيق المستخدم الرئيسي أو آخر نشاط شاهده المستخدم، قبل الأنواع الأخرى من العمليات. يمكن أيضًا تطبيق سياسات أخرى لإيقاف العمليات، مثل ضبط حدود صارمة لعدد العمليات المسموح بها أو الحد من المدّة التي يمكن أن تبقى فيها العملية محفوظة في ذاكرة التخزين المؤقت باستمرار.
لا تتوفّر سوى بضع عمليات من هذا النوع في النظام، ولا يتم إغلاقها إلا كحل أخير إذا كانت الذاكرة منخفضة جدًا لدرجة أنّه لا يمكن حتى لهذه العمليات مواصلة العمل. بشكل عام، إذا حدث ذلك، يعني ذلك أنّ الجهاز وصل إلى حالة ذاكرة التخزين المؤقت، لذا يكون هذا الإجراء مطلوبًا للحفاظ على استجابة واجهة المستخدم.
عند تحديد كيفية تصنيف عملية معيّنة، يستند النظام إلى المستوى
الأكثر أهمية من بين جميع المكوّنات النشطة حاليًا في العملية.
اطّلِع على مستندات Activity
وService
و
BroadcastReceiver
للحصول على مزيد من التفاصيل حول كيفية مساهمة كلّ من هذه المكوّنات في دورة حياة العملية و
التطبيق بشكل عام.
قد تزيد أيضًا أولوية العملية استنادًا إلى التبعيات الأخرى التي ترتبط بها العملية. على سبيل المثال، إذا كانت العملية "أ" مرتبطة بملف تعريف
Service
باستخدام العلامة
Context.BIND_AUTO_CREATE
أو تستخدم ملف تعريف
ContentProvider
في العملية "ب"، يكون تصنيف العملية "ب"
دائمًا مهمًا على الأقل بقدر تصنيف العملية "أ".