في نظام التشغيل Android 9 (والإصدارات الأقدم)، كانت التطبيقات تدخل في حالة PAUSED عندما:
- تم إطلاق نشاط جديد وشفّاف فوق التطبيق، بينما كان التطبيق لا يزال مرئيًا (وبالتالي، لم يتم إيقافه).
- فقد النشاط التركيز، ولكنّه لم يكن محجوبًا وكان بإمكان المستخدم التفاعل معه. على سبيل المثال، في وضع النوافذ المتعددة، يمكن أن يظهر عدد من الأنشطة ويتلقّى إدخالات باللمس في الوقت نفسه.
تختلف هذه الحالات في مقدار الإيقاف المؤقت الذي يجب أن يجريه التطبيق، ولكن لا يمكن التمييز بينها على مستوى التطبيق.
في Android 10، تكون جميع الأنشطة التي يمكن التركيز عليها في الحِزم المرئية في الحالة RESUMED. ويحسّن ذلك التوافق مع وضعَي النوافذ المتعددة وMD للتطبيقات التي تستخدم onPause() بدلاً من onStop() لإيقاف إعادة تحميل واجهة المستخدم والتفاعل مع المستخدم. ويعني ذلك ما يلي:
- يتم استئناف كلا النشاطَين في وضع تقسيم الشاشة.
- يتم استئناف جميع الأنشطة الظاهرة في الأعلى في وضع النوافذ الحرة.
- يمكن استئناف الأنشطة على شاشات متعددة في الوقت نفسه.

الشكل 1: ميزة "استئناف متعدد" على جهاز قابل للطي

الشكل 2: استئناف متعدّد في وضع الكمبيوتر المكتبي
يمكن أن تكون الأنشطة في حالة PAUSED عندما يتعذّر التركيز عليها أو عندما تكون محجوبة جزئيًا، مثل:
- في وضع تقسيم الشاشة المصغّر (مع تشغيل المشغّل على الجانب)، لا يتم استئناف النشاط العلوي لأنّه غير قابل للتركيز.
- في وضع "نافذة ضمن النافذة"، لا يتم استئناف النشاط لأنّه غير قابل للتركيز.
- عندما تكون الأنشطة مشمولة بأنشطة شفافة أخرى في الحزمة نفسها
تشير هذه الطريقة إلى التطبيقات بأنّ النشاط يمكنه تلقّي إدخال من المستخدم فقط في الحالة RESUMED. قبل الإصدار 10 من نظام التشغيل Android،
كان بإمكان الأنشطة أيضًا تلقّي إدخال في الحالة PAUSED (على سبيل المثال، جرِّب لمس
كلا النشاطين في وضع تقسيم الشاشة في الوقت نفسه على جهاز يعمل بالإصدار 9 من نظام التشغيل Android).
للحفاظ على إشارة استئناف من إصدارات Android السابقة (ولتحديد الوقت الذي يجب أن تحصل فيه التطبيقات على إذن الوصول إلى الموارد ذات الوصول الحصري أو الموارد الفردية)، يتضمّن نظام التشغيل Android 10 دالة رد نداء جديدة:
Activity#onTopResumedActivityChanged(boolean onTop)
عند استدعاء دالة ردّ الاتصال هذه، يتم استدعاؤها بين Activity#onResume() وActivity#onPause(). هذا الإجراء الاختياري يمكن تخطّيه،
وبالتالي يمكن أن تنتقل حالة النشاط من RESUMED إلى PAUSED
بدون أن يصبح النشاط في المقدّمة على النظام. على سبيل المثال، في وضع النوافذ المتعددة
بما أنّ عملية الاستدعاء هذه اختيارية، فهي ليست جزءًا من Activity
Lifecycle ويجب استخدامها نادرًا.
يتلقّى النشاط السابق الذي تم استئنافه في المقدّمة وينتهي من تنفيذ onTopResumedActivity(false) قبل أن يتلقّى النشاط التالي الذي تم استئنافه في المقدّمة onTopResumedActivity(true)، ما لم يستغرق النشاط السابق وقتًا طويلاً جدًا في معالجة استدعاء الطريقة ويتجاوز المهلة البالغة 500 ملي ثانية.
التوافق
للحفاظ على التوافق عند تنفيذ ميزة "استئناف التشغيل المتعدّد"، ننصحك بتجربة الحلول التالية.
أنشطة متعدّدة تم استئنافها في عملية تطبيق واحدة
- المشكلة في الإصدار 9 من نظام التشغيل Android والإصدارات الأقدم، لا يتم استئناف سوى نشاط واحد في النظام في كل مرة. تتضمّن جميع عمليات الانتقال بين الأنشطة إيقاف نشاط مؤقتًا قبل استئناف نشاط آخر. تستفيد بعض التطبيقات والأُطر (مثل Flutter أو LocalActivityManager في Android) من هذه الحقيقة، وتخزِّن الحالة المتعلقة بالنشاط الذي تم استئنافه في عناصر أحادية.
- الحل في الإصدار 9 من نظام التشغيل Android والإصدارات الأقدم، إذا تم استئناف نشاطَين من العملية نفسها، سيستأنف النظام النشاط الذي يقع في ترتيب Z الأعلى فقط. يمكن للتطبيقات التي تستهدف الإصدار 10 من نظام التشغيل Android أن تتيح استئناف أنشطة متعددة في الوقت نفسه.
الوصول إلى الكاميرا في الوقت نفسه
- المشاكل تحدث هذه المشاكل أيضًا في نظام التشغيل Android 9 والإصدارات الأقدم. على سبيل المثال، يمكن أن يفقد نشاط بملء الشاشة ومستأنَف تركيز الكاميرا لصالح نشاط متوقف مؤقتًا في الأعلى في وضع "نافذة ضمن النافذة"، ولكن يصبح أكثر عرضةً مع زيادة استخدام وضعَي النوافذ المتعددة والشاشات المتعددة.
- بسبب التغييرات التي تم إجراؤها على حالة
RESUME، قد يتم فصل التطبيقات عن الكاميرا حتى أثناء استئنافها. ولحلّ هذه المشكلة، يجب أن تتمكّن التطبيقات من التعامل مع انقطاع اتصال الكاميرا بدون تعطُّل. عند قطع الاتصال، تتلقّى التطبيقات دالة ردّ عند قطع الاتصال، وتبدأ جميع طلبات البيانات من واجهة برمجة التطبيقات في عرضCameraAccessException. - لا يضمن وضع "
resizeableActivity=false" إمكانية الوصول الحصري إلى الكاميرا، لأنّه يمكن فتح تطبيقات أخرى تستخدم الكاميرا على شاشات أخرى.
- بسبب التغييرات التي تم إجراؤها على حالة
- الحلول على المطوّرين تضمين منطق لتحديد الحالات التي يتم فيها فصل التطبيق عن الكاميرا. إذا تم فصل تطبيق عن الكاميرا، عليه مراقبة عمليات معاودة الاتصال المتاحة بالكاميرا لمحاولة إعادة الاتصال ومواصلة استخدام الكاميرا. بالإضافة إلى دالة
CameraManager#AvailabilityCallback#onCameraAvailable()الحالية، أضاف نظام التشغيل Android 10 دالةCameraManager#AvailabilityCallback#onCameraAccessPrioritiesChanged()، التي تغطي حالة التبديل بين عدة أنشطة تم استئنافها (وإعطاء الأولوية للكاميرا). على مطوّري التطبيقات استخدام كلتا دالتَي معاودة الاتصال هاتين لتحديد الوقت المناسب لمحاولة الحصول على إذن الوصول إلى الكاميرا.
استئناف متعدّد
في نظام التشغيل Android 10، يتم تحديد حالة مراحل النشاط حسب مستوى العرض ومستوى Z. لضمان الحالة الصحيحة بعد تعديلات مستوى الظهور في نشاط وتقييم حالة مراحل النشاط السارية، استدعِ طريقة ActivityRecord#makeActiveIfNeeded() من مواقع مختلفة. في نظام التشغيل Android 10، يعني "نشط" إما RESUMED أو PAUSED، ولا يعمل إلا في هاتين الحالتين.
في نظام التشغيل Android 10، يتم تتبُّع استئناف نشاط بشكل منفصل في كل حزمة بدلاً من تتبُّعه في مكان واحد في النظام. ويرجع ذلك إلى إمكانية تنفيذ العديد من عمليات الانتقال بين الأنشطة في الوقت نفسه في أوضاع النوافذ المتعددة. للحصول على التفاصيل، يُرجى الاطّلاع على ActivityStack#mInResumeTopActivity.
معاودة الاتصال بالنشاط الأكثر استئنافًا
بعد تنفيذ إجراءات يمكن أن تؤدي إلى تغيير في النشاط الأعلى (مثل بدء النشاط أو استئنافه أو تغيير ترتيبه حسب المحور Z)، يتم استدعاء ActivityStackSupervisor#updateTopResumedActivityIfNeeded(). تتحقّق هذه الطريقة مما إذا كان النشاط الذي تم استئنافه في الأعلى قد تغيّر، وتجري التعديل إذا لزم الأمر. إذا لم يحرّر النشاط السابق الذي تم استئنافه في المقدّمة حالة الاستئناف في المقدّمة، سيتم إرسال رسالة تفيد بفقدان حالة الاستئناف في المقدّمة إليه، وسيتم تحديد مهلة على مستوى الخادم (ActivityStackSupervisor#scheduleTopResumedStateLossTimeout()). يتم إرسال تقرير عن حالة الاستئناف في المقدّمة إلى النشاط التالي بعد أن يحرّر النشاط السابق الحالة، أو عند انتهاء المهلة (راجِع استخدامات:
ActivityStackSupervisor#scheduleTopResumedActivityStateIfNeeded()
تمت إضافة عنصر معاملة TopResumedActivityChangeItem جديد
للإبلاغ عن أهم التغييرات في الحالة التي تم استئنافها إلى العملاء، ويستفيد من
بنية ActivityLifecycler من Android 9.
يتم تخزين حالة الإيقاف المؤقت الأخيرة في جهة العميل، وفي كل مرة تنتقل فيها الحالة إلى RESUMED أو PAUSED، يتم أيضًا التحقّق مما إذا كان يجب استدعاء معاودة الاتصال onTopResumedActivityChanged(). يتيح ذلك فصلًا معيّنًا في عملية نقل حالات دورة الحياة وحالة الاستئناف الأعلى بين جهة الخادم وجهة العميل.