استئناف متعدد

في الإصدار 9 من نظام Android (والإصدارات الأقدم)، كانت التطبيقات تدخل في الحالة PAUSED في الحالات التالية:

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

تختلف هذه الحالات في عدد الإيقاف المؤقت الذي يجب أن يتخذه التطبيق، ولكن لا يمكن تمييزه على مستوى التطبيق.

في نظام Android 10، تتوفّر جميع الأنشطة التي يمكن التركيز عليها في الحزم المرئية في الحالة RESUMED. ويؤدي ذلك إلى تحسين التوافق مع وضعَي النوافذ المتعددة ووضع المدير الفرعي للتطبيقات التي تستخدم 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 والإصدارات الأقدم، إذا تم استئناف نشاطَين من العملية نفسها ، يستأنف النظام النشاط الأعلى في الترتيب حسب الأولوية فقط. يمكن للتطبيقات التي تستهدف الإصدار 10 من Android السماح باستئناف أنشطة متعددة في الوقت نفسه.

الوصول إلى الكاميرا في آنٍ واحد

  • المشاكل: وتظهر هذه المشاكل أيضًا في الإصدار 9 من نظام التشغيل Android والإصدارات الأقدم. على سبيل المثال، يمكن أن يفقد نشاط مُستَمَد من شاشة ملء الشاشة ونشاط مُستَمَد من شاشة متوقفة مؤقتًا تركيز الكاميرا في وضع "نافذة ضمن نافذة"، ولكن يمكن أن يصبح النشاط أكثر ظهورًا مع استخدام ميزتَي "وضع النوافذ المتعددة" و"وضع الشاشات المتعددة" بشكل أوسع نطاقًا.
    • بسبب التغييرات التي تم إجراؤها على حالة 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(). يتيح ذلك فصلًا معيّنًا في إرسال حالات دورة الحياة والحالة التي تم استئنافها مؤخرًا بين جانبَي الخادم والعميل.