في نظام التشغيل Android 9 (والإصدارات الأقدم)، كان يتم إدخال التطبيقات في حالة PAUSED
عند:
- تم إطلاق نشاط جديد وشفّاف فوق التطبيق، بينما كان التطبيق لا يزال مرئيًا (وبالتالي، لم يتم إيقافه).
- فقد النشاط التركيز، ولكنّه لم يكن محجوبًا وكان بإمكان المستخدم التفاعل معه. على سبيل المثال، في وضع النوافذ المتعددة، يمكن أن يظهر عدد من الأنشطة ويتلقّى إدخالات باللمس في الوقت نفسه.
تختلف هذه الحالات في مقدار الإيقاف المؤقت الذي يجب أن يجريه التطبيق، ولكن لا يمكن التمييز بينها على مستوى التطبيق.
في Android 10، تكون جميع الأنشطة التي يمكن التركيز عليها في الحِزم المرئية في الحالة RESUMED
. يؤدي ذلك إلى تحسين التوافق مع وضعَي النوافذ المتعددة وMD للتطبيقات التي تستخدم onPause()
بدلاً من onStop()
لإيقاف إعادة تحميل واجهة المستخدم والتفاعل مع المستخدم. ويعني ذلك ما يلي:
- يتم استئناف كلا النشاطَين في وضع تقسيم الشاشة.
- يتم استئناف جميع الأنشطة الظاهرة في الأعلى في وضع النوافذ الحرة.
- يمكن استئناف الأنشطة على شاشات متعددة في الوقت نفسه.
الشكل 1. استئناف التشغيل على جهاز قابل للطي
الشكل 2. استئناف تنزيل ملفات متعددة في وضع الكمبيوتر المكتبي
يمكن أن تكون الأنشطة في حالة PAUSED
عندما يتعذّر التركيز عليها أو عندما تكون محجوبة جزئيًا، مثل:
- في وضع تقسيم الشاشة المصغّر (مع تشغيل المشغّل على الجانب)، لا يتم استئناف النشاط العلوي لأنّه غير قابل للتركيز.
- في وضع "نافذة ضمن النافذة"، لا يتم استئناف النشاط لأنّه لا يمكن التركيز عليه.
- عندما تكون الأنشطة مشمولة بأنشطة شفافة أخرى في الحزمة نفسها
تشير هذه الطريقة إلى التطبيقات بأنّ النشاط يمكنه تلقّي إدخال من المستخدم فقط في حالة RESUMED
. قبل الإصدار 10 من نظام التشغيل Android،
كان بإمكان الأنشطة أيضًا تلقّي إدخال في الحالة PAUSED
(على سبيل المثال، جرِّب لمس
كلا النشاطين في وضع تقسيم الشاشة في الوقت نفسه على جهاز يعمل بالإصدار 9 من نظام التشغيل Android).
للحفاظ على إشارة resumed من إصدارات 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 إتاحة استئناف أنشطة متعددة في الوقت نفسه.
الوصول المتزامن إلى الكاميرا
- المشاكل تظهر هذه المشاكل أيضًا في الإصدار 9 من نظام التشغيل Android والإصدارات الأقدم. على سبيل المثال، يمكن أن يفقد نشاط بملء الشاشة ومستأنَف تركيز الكاميرا لصالح نشاط متوقف مؤقتًا في الأعلى في وضع "نافذة ضمن النافذة"، ولكن يصبح أكثر عرضةً مع زيادة استخدام وضعَي النوافذ المتعددة والشاشات المتعددة.
- بسبب التغييرات التي تم إجراؤها على حالة
RESUME
، قد يتم فصل التطبيقات عن الكاميرا حتى أثناء استئنافها. لحلّ هذه المشكلة، يجب أن تتمكّن التطبيقات من التعامل مع انقطاع اتصال الكاميرا بدون تعطُّل. عند قطع الاتصال، تتلقّى التطبيقات دالة ردّ عند قطع الاتصال، وتبدأ جميع طلبات البيانات من واجهة برمجة التطبيقات في عرضCameraAccessException
. - لا يضمن وضع
resizeableActivity=false
إمكانية الوصول الحصري إلى الكاميرا، لأنّه يمكن فتح تطبيقات أخرى تستخدم الكاميرا على شاشات أخرى.
- بسبب التغييرات التي تم إجراؤها على حالة
- الحلول على المطوّرين تضمين منطق لتحديد الحالات التي يتم فيها فصل التطبيق عن الكاميرا. في حال تم فصل تطبيق عن الكاميرا، يجب أن يستمع إلى عمليات معاودة الاتصال بشأن توفّر الكاميرا لمحاولة إعادة الاتصال ومواصلة استخدام الكاميرا. بالإضافة إلى
CameraManager#AvailabilityCallback#onCameraAvailable()
الحالية، أضاف نظام التشغيل Android 10CameraManager#AvailabilityCallback#onCameraAccessPrioritiesChanged()
، التي تغطي حالة التبديل بين عدة أنشطة مستأنَفة من حيث التركيز (وأولوية الكاميرا). على مطوّري التطبيقات استخدام كلتا دالتَي معاودة الاتصال هاتين لتحديد الوقت المناسب لمحاولة الحصول على إذن الوصول إلى الكاميرا.
استئناف متعدد
في Android 10، يتم تحديد حالة مراحل نشاط التطبيق حسب مستوى الظهور وترتيب Z. لضمان الحالة الصحيحة بعد تعديلات مستوى الظهور في نشاط وتقييم حالة مراحل النشاط السارية، استدعِ طريقة ActivityRecord#makeActiveIfNeeded()
من مواقع مختلفة. في نظام التشغيل Android 10، يعني "نشط" إما RESUMED
أو PAUSED
، ولا يعمل إلا في هاتين الحالتين.
في Android 10، يتم تتبُّع استئناف نشاط بشكل منفصل في كل حزمة بدلاً من تتبُّعه في مكان واحد في النظام. ويرجع ذلك إلى إمكانية تنفيذ العديد من عمليات الانتقال بين الأنشطة في الوقت نفسه في أوضاع النوافذ المتعددة. للحصول على التفاصيل، يُرجى الاطّلاع على ActivityStack#mInResumeTopActivity
.
معاودة الاتصال بالنشاط الأكثر استئنافًا
بعد تنفيذ إجراءات يمكن أن تؤدي إلى تغيير في النشاط الأعلى (مثل بدء نشاط أو استئنافه أو تغيير ترتيبه حسب المحور Z)، يتم استدعاء ActivityStackSupervisor#updateTopResumedActivityIfNeeded()
. تتحقّق هذه الطريقة مما إذا كان النشاط الذي تم استئنافه في الأعلى قد تغيّر، وتجري التعديل إذا لزم الأمر. إذا لم يحرِّر النشاط السابق الذي تم استئنافه في المقدّمة حالة الاستئناف في المقدّمة، سيتم إرسال رسالة top-resumed-state-loss إليه وتحديد مهلة زمنية على مستوى الخادم (ActivityStackSupervisor#scheduleTopResumedStateLossTimeout()
). يتم إرسال تقرير عن حالة الاستئناف في المقدّمة إلى النشاط التالي بعد أن يحرِّر النشاط السابق الحالة، أو عند انتهاء المهلة الزمنية (راجِع استخدامات:
ActivityStackSupervisor#scheduleTopResumedActivityStateIfNeeded()
تمت إضافة عنصر معاملة TopResumedActivityChangeItem
جديد
للإبلاغ عن تغييرات الحالة التي تم استئنافها بشكل متكرر إلى العملاء، ويستفيد من
بنية ActivityLifecycler
من Android 9.
يتم تخزين حالة الإيقاف المؤقت الأخيرة على جهة العميل، وفي كل مرة تنتقل فيها الحالة إلى RESUMED
أو PAUSED
، يتم أيضًا التحقّق مما إذا كان يجب استدعاء معاودة الاتصال onTopResumedActivityChanged()
. يتيح ذلك فصلًا معيّنًا في عملية نقل حالات دورة الحياة وحالة الاستئناف الأعلى بين جهة الخادم وجهة العميل.