تتناول هذه الصفحة بعض الأسباب الشائعة لتعذُّر تشغيل الخدمات التي تعمل في المقدّمة، وتساعدك في تحديد سبب المشكلة.
يتناول هذا المستند المشاكل التالية:
قبل تحديد المشاكل وحلّها
التحقّق من التغييرات الأخيرة في الخدمات التي تعمل في المقدّمة
في حال استخدام الخدمات التي تعمل في المقدّمة بشكل غير صحيح، يمكن أن يكون لها تأثيرات سلبية على أداء الجهاز وعمر البطارية. لهذا السبب، غالباً ما تُجري إصدارات نظام التشغيل Android تغييرات على سلوك الخدمات التي تعمل في المقدّمة للحد من هذه الآثار السلبية.
إذا كنت تواجه مشكلة في الخدمات التي تعمل في المقدّمة، عليك الاطّلاع على مستندات التغييرات التي طرأت على الخدمات التي تعمل في المقدّمة والتحقّق ممّا إذا كانت هناك أي تغييرات حديثة يمكن أن تفسّر مشاكلك. من المهم بشكل خاص التحقّق من التغييرات في الحالات التالية:
- عدم عمل رمز الخدمة التي تعمل في المقدّمة والذي كان يعمل سابقًا
- إذا كنت قد بدأت للتو اختبار إصدار نظام أساسي جديد أو غيّرت مستوى واجهة برمجة التطبيقات الذي يستهدفه تطبيقك
بالإضافة إلى ذلك، إذا كنت تختبر جهازك باستخدام إصدار تجريبي للمطوّرين من ال platfrom، احرص على الاطّلاع على أحدث إصدار من مستندات الإصدار التجريبي للمطوّرين.
أخطاء "التطبيق لا يستجيب" (ANR)
في بعض الحالات، من المتوقّع أن يوقف التطبيق خدمته التي تعمل في المقدّمة. إذا لم يوقف التطبيق الخدمة، سيوقفها النظام ويؤدي إلى خطأ "التطبيق لا يستجيب".
خدمة قصيرة تستغرق وقتًا طويلاً جدًا، ما يؤدي إلى حدوث خطأ ANR
يجب أن تكتمل الخدمات التي تعمل في المقدّمة وتستخدم نوع الخدمة القصيرة
بشكل سريع، في غضون ثلاث دقائق تقريبًا. عند انتهاء الوقت،
يُستدعي النظام Service.onTimeout(int,int)
في الخدمة. أمام الخدمة
بضع ثوانٍ للاتصال برقم stopSelf()
. إذا لم توقف الخدمة نفسها، يُطلق النظام خطأ "التطبيق لا يستجيب".
التشخيص:
إذا كان خطأ ANR ناتجًا عن تعذُّر إيقاف خدمة تعمل في المقدّمة من نفسها، يُرسِل النظام استثناءً داخليًا. يمكنك التأكّد من أنّ هذه هي المشكلة من خلال التحقّق من Logcat. في هذه الحالة، يتضمّن السجلّ الرسالة التالية:
Fatal Exception: android.app.RemoteServiceException: "A foreground service of
type FOREGROUND_SERVICE_TYPE_SHORT_SERVICE did not stop within its timeout:
[component name]"
الإصلاح:
تأكَّد من أنّ جميع الخدمات التي تعمل في المقدّمة وذات المدة الزمنية المحدودة تنتهي من عملها وتُجري طلبًا لسماح بالوصول إلى stopForeground(int)
خلال الحدّ الزمني الذي يحدّده النظام.
أن تنفِّذ خدماتك التي تعمل في المقدّمة Service.onTimeout(int,int)
تأكَّد من أنّ تنفيذ هذه الطريقة يستدعي stopSelf()
على الفور.
استثناءات الخدمات التي تعمل في المقدّمة
يوضّح هذا القسم العديد من المشاكل المتعلّقة بالخدمة التي تعمل في المقدّمة والتي يمكن أن تؤدي إلى طرح النظام استثناءً. إذا لم يرصد التطبيق الاستثناء، سيظهر للمستخدم مربّع حوار يُعلمه بأنّ التطبيق قد توقّف.
في بعض الحالات، يُرسِل النظام استثناءً داخليًا. لا يمكنك رصد هذه الاستثناءات، ولكن يمكنك البحث في Logcat لمعرفة نوع الاستثناء الذي تم طرحه.
استثناء داخلي: انتهت المهلة
يفرض النظام حدًا أقصى على المدة التي يمكن أن تعمل فيها خدمات مزامنة البيانات ومعالجة الوسائط في المقدّمة عندما يكون التطبيق في الخلفية. إذا تجاوزت
الخدمة هذا الحدّ، يستدعي النظام طريقة
Service.onTimeout(int,int)
في الخدمة. تتوفّر للخدمة بضع ثوانٍ للاتصال بالرقم stopSelf()
. إذا لم توقف الخدمة نفسها، يُنشئ النظام
استثناءً داخليًا يؤدي إلى تعطُّل التطبيق.
التشخيص:
إذا كان السبب هو تجاوز مهلة الانتظار، يتضمّن Logcat الرسالة التالية:
Fatal Exception: android.app.RemoteServiceException: "A foreground service of
type [service type] did not stop within its timeout: [component name]"
الإصلاح:
تأكَّد من أنّ جميع الخدمات التي تعمل في المقدّمة وذات المدة الزمنية المحدودة تنتهي من عملها وتُجري طلبًا لstopForeground(int)
خلال الحدّ الزمني للنظام.
أن تنفِّذ خدماتك التي تعمل في المقدّمة Service.onTimeout(int,int)
تأكَّد من أنّ تنفيذ هذه الطريقة يستدعي stopSelf()
على الفور.
الاستثناء الداخلي: ForegroundServiceDidNotStartInTimeException
عند تشغيل خدمة من خلال استدعاء context.startForegroundService()
، تتمكّن هذه الخدمة من ترقية نفسها إلى خدمة تعمل في المقدّمة من خلال استدعاء ServiceCompat.startForeground()
في غضون بضع ثوانٍ.
وإذا لم تفعل ذلك، يُطلق النظام خطأ ANR.
التشخيص:
إذا لم تبدأ خدمة تعمل في المقدّمة في الوقت المناسب، سيتعطّل التطبيق، ما سيؤدي إلى ظهور مربع حوار توقّف التطبيق أمام العميل. في هذه الحالة، يمكنك العثور على الرسالة التالية في Logcat:
android.app.RemoteServiceException$ForegroundServiceDidNotStartInTimeException:
Context.startForegroundService() did not then call Service.startForeground()
الإصلاح:
تأكَّد من أنّ جميع الخدمات التي تعمل في المقدّمة والتي تم إنشاؤها حديثًا تستدعي
ServiceCompat.startForeground()
في غضون بضع ثوانٍ.
ForegroundServiceStartNotAllowedException
الخطأ:
يُرسِل النظام الخطأ ForegroundServiceStartNotAllowedException
.
السبب:
ويحدث ذلك عادةً عندما يشغِّل التطبيق خدمة تعمل في المقدّمة من الخلفية بدون الحصول على إعفاء صالح.
بدءًا من Android 12 (المستوى 31 لواجهة برمجة التطبيقات)، لا يُسمح للتطبيقات ببدء خدمات تعمل في المقدّمة عندما يكون التطبيق قيد التشغيل في background، مع بعض الاستثناءات المحدّدة.
إذا حاولت بدء خدمة تعمل في المقدّمة من الخلفية ولم يتم
استيفاء متطلبات أحد الاستثناءات، يُرسِل النظام سوىForegroundServiceStartNotAllowedException
. وينفّذ النظام ذلك أيضًا في حال عدم استيفاء متطلبات الإعفاء.
على سبيل المثال، قد يتضمّن التطبيق زرًا يمكن للمستخدم النقر عليه، ما يؤدي إلى تنفيذ
التطبيق لبعض عمليات المعالجة ثم تشغيل خدمة تعمل في المقدّمة. في هذه الحالة،
يمكن أن ينقر المستخدم على الزر ثم يضع
التطبيق في الخلفية على الفور. في هذه الحالة، سيحاول التطبيق تشغيل الخدمة
من الخلفية. إذا لم يستوفِ التطبيق أحد الاستثناءات المحدّدة،
يُرسِل النظام ForegroundServiceStartNotAllowedException
.
بالإضافة إلى ذلك، تسري بعض الإعفاءات لفترة زمنية قصيرة. على سبيل المثال، هناك استثناء قصير إذا كان تطبيقك يشغّل خدمة تعمل في المقدّمة
استجابةً لرسالة "المراسلة عبر السحابة الإلكترونية من Firebase" ذات الأولوية العالية. إذا لم تبدأ الخدمة
بسرعة كافية، ستظهر لك علامة ForegroundServiceStartNotAllowedException
.
في بعض الأحيان، تصبح بعض الاستثناءات أكثر تقييدًا مع إصدارات Android الجديدة. إذا غيّرت إصدار Android الذي يستهدفه تطبيقك، راجِع مستندات التغييرات في خدمات foreground وتأكَّد مما إذا كان تطبيقك لا يزال يستوفي أحد الاستثناءات المسموح بها.
الإصلاح:
غيِّر سير عمل تطبيقك كي لا يحتاج إلى تشغيل خدمات تعمل في المقدّمة عندما يكون التطبيق في الخلفية، أو تأكَّد من أنّ تطبيقك يستوفي أحد الإعفاءات.
يمكنك استخدام مكونات دورة النشاط، مثل LiveData
لإدارة
مراحل نشاط تطبيقك كي لا تحاول عن غير قصد بدء
خدمة تعمل في المقدّمة من الخلفية.
SecurityException
الخطأ:
يُرسِل النظام الخطأSecurityException
.
السبب:
حاول تطبيقك تشغيل خدمة تعمل في المقدّمة بدون الحصول على الأذونات اللازمة.
- إذا كان التطبيق يستهدف الإصدار 9 من نظام التشغيل Android (المستوى 28 لواجهة برمجة التطبيقات) أو إصدارًا أحدث، يجب أن يكون لديه إذن
FOREGROUND_SERVICE
لبدء خدمة تعمل في المقدّمة. - إذا كان التطبيق يستهدف الإصدار 14 من نظام التشغيل Android (المستوى 34 لواجهة برمجة التطبيقات) أو الإصدارات الأحدث، يجب أن يستوفي جميع الشروط المسبقة لنوع الخدمة التي تعمل في المقدّمة. يمكنك الاطّلاع على تفاصيل هذه المتطلبات الأساسية في مستندات أنواع الخدمات التي تعمل في المقدّمة. وعلى وجه التحديد، يُرجى مراعاة المتطلبات التالية:
- تتطلّب العديد من أنواع الخدمات التي تعمل في المقدّمة أذونات وقت التشغيل المحدّدة. على سبيل المثال، يجب أن يكون لدى الخدمة التي تعمل في المقدّمة للرسائل عن بُعد إذن
FOREGROUND_SERVICE_REMOTE_MESSAGING
.
- تتطلّب العديد من أنواع الخدمات التي تعمل في المقدّمة أذونات وقت التشغيل المحدّدة. على سبيل المثال، يجب أن يكون لدى الخدمة التي تعمل في المقدّمة للرسائل عن بُعد إذن
- في العديد من الحالات، يتم فرض قيود إضافية أثناء الاستخدام على
الأذونات التي تحتاجها بعض أنواع الخدمات التي تعمل في المقدّمة. ولا يتم منح هذه الأذونات
للتطبيق إلا عندما يكون في المقدّمة (باستثناء بعض
الحالات المحدّدة). وهذا يعني أنّه حتى إذا طلب
تطبيقك أحد هذين الإذنَين وحصل عليه، إذا حاول التطبيق
بدء الخدمة التي تعمل في المقدّمة عندما يكون التطبيق قيد التشغيل في الخلفية،
سيُرسِل النظام خطأ
SecurityException
حتى إذا كان التطبيق يملك استثناءً لبدء خدمة تعمل في المقدّمة من الخلفية. لمزيد من المعلومات، يُرجى الاطّلاع على القيود المفروضة على بدء الخدمات التي تعمل في المقدّمة وتحتاج إلى أذونات أثناء الاستخدام.- قد تتلقّى خطأ
SecurityException
إذا طلبت الأذونات اللازمة وبدأت الخدمة التي تعمل في المقدّمة قبل تأكيد منح الأذونات المطلوبة.
- قد تتلقّى خطأ
الإصلاح:
قبل تشغيل الخدمة التي تعمل في المقدّمة، اطلب جميع أذونات الخدمة المناسبة التي تعمل في المقدّمة، وتأكَّد من استيفاء جميع المتطلبات الأساسية الأخرى المتعلقة بوقت التشغيل.