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

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

يتلقّى النشاط السابق الذي تم استئنافه أولاً 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.

استدعاء النشاط الأكثر استئنافًا

بعد الإجراءات التي يمكن أن تؤدي إلى تغيير في النشاط الأهم (مثل بدء النشاط أو استئنافه أو تغيير الترتيب حسب العمق)، يتمّ استدعاء ActivityStackSupervisor#updateTopResumedActivityIfNeeded(). تتحقّق هذه المحاولة مما إذا كان النشاط الذي تم استئنافه في أعلى الصفحة قد تغيّر، وتجرِي التعديل إذا لزم الأمر. إذا لم يُلغِ النشاط السابق الذي تم استئنافه أولاً حالة "تم استئنافه أولاً"، يتم إرسال رسالة فقدان حالة "تم استئنافه أولاً" إليه ويتم تحديد مهلة على جانب الخادم (ActivityStackSupervisor#scheduleTopResumedStateLossTimeout()). يتم إرسال تقرير عن حالة "تم استئنافه أولاً" إلى النشاط التالي بعد أن ألغى النشاط السابق الحالة، أو عند انتهاء المهلة (راجِع استخدامات:

ActivityStackSupervisor#scheduleTopResumedActivityStateIfNeeded()

تمت إضافة عنصر معاملة TopResumedActivityChangeItem جديد لإبلاغ العملاء بتغييرات حالة "تم الاستئناف" الأكثر تكرارًا، والاستفادة من بنية ActivityLifecycler من Android 9.

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