إظهار الدعم

في ما يلي التعديلات التي يتم إجراؤها على هذه المواضع الخاصة بالعرض:

تغيير حجم الأنشطة والشاشات

للإشارة إلى أنّ التطبيق قد لا يتيح وضع النوافذ المتعددة أو تغيير الحجم، تستخدم السمة resizeableActivity=false. الإعدادات الشائعة تشمل المشاكل التي تواجهها التطبيقات عند تغيير حجم الأنشطة ما يلي:

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

في نظام التشغيل Android 7 (والإصدارات الأحدث)، يمكن ضبط تطبيق. تشغيل resizeableActivity=false في وضع ملء الشاشة دائمًا. ضِمن في هذه الحالة، تمنع المنصة تقسيم الأنشطة التي لا يمكن تغيير حجمها الشاشة. إذا حاول المستخدم استدعاء نشاط لا يمكن تغيير حجمه من مشغّل التطبيقات في وضع تقسيم الشاشة، يخرج النظام الأساسي من وضع تقسيم الشاشة تبدأ النشاط الذي لا يمكن تغيير حجمه في وضع ملء الشاشة.

التطبيقات التي تضبط هذه السمة صراحةً على false في يجب ألا يتم تشغيل البيان في وضع النوافذ المتعددة، ما لم يكن التوافق تطبيق الوضع التالي:

  • يتم تطبيق الإعدادات نفسها على العملية، التي تحتوي على جميع الأنشطة والمكونات غير النشطة.
  • تلبي الإعدادات المطبَّقة متطلبات بروتوكول CDD في ما يتعلق بالتوافق مع التطبيق. ما يعرضه.

في Android 10، لا يزال النظام الأساسي يمنع الأنشطة التي لا يمكن تغيير حجمها من الانتقال إلى وضع تقسيم الشاشة، ولكن يمكن يتم تغيير حجمها مؤقتًا إذا كان النشاط يتضمن اتجاهًا أو جانبًا ثابتًا النسبة المئوية. وإذا لم يكن كذلك، يتم تغيير حجم النشاط لملء الشاشة بأكملها كما هو الحال في Android 9 والإصدارات الأقدم.

تطبّق عملية التنفيذ التلقائية السياسة التالية:

عندما يتبيّن أنّ أحد الأنشطة غير متوافق مع ميزة النوافذ المتعددة من خلال استخدام السمة android:resizeableActivity ومتى نشاط يستوفي أحد الشروط الموضحة أدناه، ثم عندما تنطبق من تهيئة الشاشة، ويتم حفظ النشاط والعملية مع بالتهيئة الأصلية وأن يُتاح للمستخدم إمكانية إعادة تشغيل عملية التطبيق لاستخدام إعدادات الشاشة المعدّلة

  • هو الاتجاه الثابت عبر تطبيق android:screenOrientation
  • يحتوي التطبيق على الحد الأقصى أو الحد الأدنى التلقائي لنسبة العرض إلى الارتفاع عن طريق استهداف مستوى واجهة برمجة التطبيقات. أو يفصح عن نسبة العرض إلى الارتفاع بشكل صريح

يعرِض هذا الشكل نشاطًا لا يمكن تغيير حجمه بنسبة عرض إلى ارتفاع مُعرَّفة. عند طي الجهاز، يتم تصغير حجم النافذة لتناسب المنطقة أثناء الحفاظ على نسبة العرض إلى الارتفاع باستخدام المحتوى المُعدّ للعرض على شاشة عريضة أفقيًا. بالإضافة إلى ذلك، يتوفر خيار نشاط إعادة التشغيل للمستخدم في كل مرة تكون فيها منطقة عرض تغيير النشاط.

عند فتح الجهاز، يتم ضبط الإعدادات والحجم ونسبة العرض إلى الارتفاع لا يتغير النشاط، ولكن يظهر خيار إعادة بدء النشاط.

عند عدم ضبط السمة resizeableActivity (أو ضبطها على true)، يتيح التطبيق تغيير الحجم بالكامل.

التنفيذ

يسمى النشاط الذي لا يمكن تغيير حجمه ذي الاتجاه الثابت أو نسبة العرض إلى الارتفاع الثابتة وضع توافق الحجم (SCM) في الرمز البرمجي يتم تحديد الشرط في ActivityRecord#shouldUseSizeCompatMode() متى يكون نشاط SCM تم إطلاقه، يتم إصلاح التهيئة المتعلقة بالشاشة (مثل الحجم أو الكثافة) في إعدادات الإلغاء المطلوبة، بحيث لا يعتمد النشاط بعد الآن على إعدادات العرض الحالية.

إذا لم يتمكن نشاط SCM من ملء الشاشة بأكملها، فسيتم المحاذاة إلى أعلى في منتصف أفقي. يتم احتساب حدود النشاط حسب AppWindowToken#calculateCompatBoundsTransformation()

عندما يستخدم أحد أنشطة SCM إعدادات شاشة مختلفة عن الحاوية (على سبيل المثال، يتم تغيير حجم شاشة العرض أو يتم نقل النشاط إلى حاوية أخرى العرض)، تكون قيمة ActivityRecord#inSizeCompatMode() صحيحة يتلقّى SizeCompatModeActivityController (في واجهة مستخدم النظام) لعرض زر إعادة تشغيل العملية.

أحجام شاشة العرض ونِسب العرض إلى الارتفاع فيها

يتوافق Android 10 مع نِسب عرض إلى ارتفاع جديدة. من النسب العالية للشاشات الطويلة والرقيقة إلى النسب 1:1. يمكن للتطبيقات تحديد ApplicationInfo#maxAspectRatio وApplicationInfo#minAspectRatio من الشاشة التي قادرًا على التعامل معها.

نِسب التطبيقات في Android 10

الشكل 1. أمثلة على نِسب التطبيقات المتوافقة مع نظام التشغيل Android 10

يمكن أن تتضمن عمليات تنفيذ الأجهزة شاشات ثانوية ذات أحجام بدرجات دقة أصغر من تلك المطلوبة في Android 9 وأقل (2.5 كحد أدنى بوصة العرض أو الارتفاع، 320 وحدة بكسل مستقلة الكثافة لـ smallestScreenWidth) ولكن لا يمكن وضع سوى الأنشطة التي تدعم هذه الشاشات الصغيرة هناك.

يمكن للتطبيقات الموافقة من خلال الإعلان عن حد أدنى متوافق للحجم أصغر من أو مساويًا لحجم العرض المستهدَف يمكنك استخدام android:minHeight و android:minWidth سمات تنسيق النشاط في وبيان AndroidManifest لإجراء ذلك.

سياسات الشبكة الإعلانية

يعمل Android 10 على فصل شاشة معيّنة ونقلها من تنفيذ WindowManagerPolicy التلقائي في من PhoneWindowManager إلى الصفوف المعروضة لكل عرض، مثل:

  • حالة العرض والتدوير
  • بعض المفاتيح وتتبُّع أحداث الحركة
  • واجهة مستخدم النظام ونوافذ الديكور

في الإصدار 9 من نظام Android (الإصدارات الأقدم)، تمت معالجة فئة PhoneWindowManager. سياسات العرض، والحالة والإعدادات، والتدوير، وإطار نافذة الزينة والتتبع والمزيد. ينقل Android 10 معظم هذه المهمة إلى الفئة DisplayPolicy، باستثناء تتبع عرض التناوب، الذي تم نقل إلى DisplayRotation.

إعدادات النوافذ المعروضة

في Android 10، تشمل الأجهزة القابلة للتهيئة لكل شاشة تم توسيع إعدادات النافذة لتشمل ما يلي:

  • الوضع التلقائي لنافذة العرض
  • تجاوز القيم
  • وضع تدوير المستخدم وتدويره
  • الحجم الإجباري والكثافة ووضع القياس
  • وضع إزالة المحتوى (عند إزالة الشاشة)
  • دعم زخارف النظام وIME

تحتوي الفئة DisplayWindowSettings على إعدادات لهذه الحسابات الخيارات. يتم الاحتفاظ بها على قرص في قسم /data في display_settings.xml في كل مرة يتم فيها تغيير إعداد. بالنسبة التفاصيل، يُرجى الاطّلاع على DisplayWindowSettings.AtomicFileStorage و DisplayWindowSettings#writeSettings() يمكن للشركات المصنّعة للأجهزة تقديم القيم التلقائية في display_settings.xml للأجهزة التكوين. ومع ذلك، بما أن الملف مخزَّن في /data، قد يلزم اتخاذ إجراء إضافي لاستعادة الملف إذا تم محوه من خلال مسح.

يستخدم Android 10 تلقائيًا DisplayInfo#uniqueId كمعرّف للعرض عند الاستمرار الإعدادات. يجب ملء uniqueId لجميع الشاشات. ضِمن بالإضافة إلى ذلك، فهو مستقر مع شاشات العرض المادية والشبكة. من الممكن أيضًا استخدام منفذ العرض الفعلي كمعرّف، والذي يمكن ضبطه في DisplayWindowSettings#mIdentifier بعد كل عملية كتابة، سيتم عرض جميع الإعدادات بحيث يمكن تحديث المفتاح المستخدم لإدخال العرض في مساحة التخزين. للحصول على التفاصيل، يمكنك مراجعة معرّفات الشبكة الإعلانية الثابتة:

يتم الاحتفاظ بالإعدادات في دليل /data للسجلّ الأسباب. في الأصل، كانت تُستخدم للحفاظ على الإعدادات التي حددها المستخدم، مثل تدوير الشاشة.

معرّفات الشبكة الإعلانية الثابتة

لم يوفِّر الإصدار Android 9 (والإصدارات الأقدم) معرّفات ثابتة لشاشات العرض في إطار العمل. عند إضافة شاشة إلى النظام، القيمة السابقة للعمود "Display#mDisplayId" أو "DisplayInfo#displayId" التي تم إنشاؤها لهذه الشاشة عن طريق زيادة عدّاد ثابت. إذا أكمل النظام تمت إضافة الشاشة نفسها وإزالتها، نتج عن معرّف مختلف.

إذا كان الجهاز يتضمن عدة شاشات متاحة عند بدء التشغيل، يمكن أن تكون الشاشات محددات مختلفة حسب التوقيت. بينما يعمل Android 9 ( سابقًا) تتضمن DisplayInfo#uniqueId، لم تكن تحتوي على ما يكفي للتمييز بين الشاشات نظرًا لأن العروض المادية كانت المحددة إما local:0 أو local:1، لتمثيل الشاشة المدمجة والخارجية.

التغييرات في Android 10 DisplayInfo#uniqueId لإضافة معرّف ثابت والتمييز بين الشبكات المحلية الشاشات الافتراضية.

نوع العرض التنسيق
بالتوقيت المحلي
local:<stable-id>
الشبكة
network:<mac-address>
"Virtual" (افتراضي)
virtual:<package-name-and-name>

بالإضافة إلى التحديثات التي أُجريت على "uniqueIdDisplayInfo.address يحتوي على DisplayAddress، معرّف عرض ثابت في عمليات إعادة التشغيل. في Android 10، يتوافق DisplayAddress مع الميزات المادية والشبكة. يحتوي الحقل DisplayAddress.Physical على قيمة ثابتة المعرّف المعروض (كما هو الحال في uniqueId) ويمكن إنشاؤه باستخدام DisplayAddress#fromPhysicalDisplayId()

يوفّر Android 10 أيضًا طريقة ملائمة معلومات المنفذ (Physical#getPort()) يمكن استخدام هذه الطريقة في إطار العمل لتحديد الشاشات بشكل ثابت. على سبيل المثال، تستخدم في DisplayWindowSettings). DisplayAddress.Network على عنوان MAC ويمكن إنشاؤها باستخدام DisplayAddress#fromMacAddress()

تسمح هذه الإضافات للشركات المصنّعة للأجهزة بالتعرّف على الشاشات في إعدادات الشاشات المتعددة، وضبط إعدادات وميزات النظام المختلفة باستخدام معرّفات الشاشة الثابتة، مثل منافذ الشاشات المادية هذه هذه الطرق مخفية وهي مخصّصة فقط للاستخدام ضمن system_server

وفقًا لمعرّف عرض HWC (الذي قد يكون مبهمًا ولا يكون ثابتًا دائمًا)، هذا لإرجاع رقم منفذ 8 بت (خاص بالنظام الأساسي) يحدد موصل فعلي لإخراج الشاشة، بالإضافة إلى كائن EDID الإضافي على الشاشة. يستخلص SurfaceFlinger معلومات الشركة المصنّعة أو النموذج من EDID إلى إنشاء معرفات عرض مستقرة 64 بت المعروضة لإطار العمل. إذا كانت هذه الطريقة غير متوافق أو حدثت أخطاء، يعود SurfaceFlinger إلى وضع MD القديم. حيث يكون DisplayInfo#address قيمة خالية DisplayInfo#uniqueId غير قابل للتغيير، كما هو موضح أعلاه.

للتأكّد من توفّر هذه الميزة، شغِّل:

$ dumpsys SurfaceFlinger --display-id
# Example output.
Display 21691504607621632 (HWC display 0): port=0 pnpId=SHP displayName="LQ123P1JX32"
Display 9834494747159041 (HWC display 2): port=1 pnpId=HWP displayName="HP Z24i"
Display 1886279400700944 (HWC display 1): port=2 pnpId=AUS displayName="ASUS MB16AP"

استخدام أكثر من شاشتي عرض

في Android 9 (الإصدارات الأقدم)، SurfaceFlinger وDisplayManagerService افتراض وجود شاشتي عرض ماديتين على الأكثر بمعرّفات البيانات غير القابلة للتغيير في البرنامج و1.

بدءًا من نظام Android 10، يمكن لـ SurfaceFlinger الاستفادة من واجهة برمجة تطبيقات Device Composer (HWC) لإنشاء معرّفات عرض ثابتة، ما يتيح لها إدارة هذه المعرّفات. عدد عشوائي من العروض المادية لمزيد من المعلومات، يُرجى مراجعة معرّفات الشبكة الإعلانية الثابتة:

يمكن لإطار العمل البحث عن الرمز المميّز IBinder للحصول على العرض من خلال SurfaceControl#getPhysicalDisplayToken بعد الحصول على رقم تعريف العرض 64 بت من SurfaceControl#getPhysicalDisplayIds أو من حدث مقبس كهربائي في DisplayEventReceiver.

في نظام التشغيل Android 10 (والإصدارات الأقدم)، الشاشة الداخلية الأساسية هي تم وضع علامة "TYPE_EXTERNAL" على "TYPE_INTERNAL" وجميع الشاشات الثانوية. بغض النظر عن نوع الاتصال. ولذلك، يتم التعامل مع شاشات العرض الداخلية الإضافية على أنها شاشات خارجية. وكحل بديل، يمكن للرمز البرمجي الخاص بالجهاز وضع افتراضات حول DisplayAddress.Physical#getPort إذا كان HWC معروفًا وتخصيص المنفذ المنطق يمكن التنبؤ به.

تمت إزالة هذا القيد في نظام التشغيل Android 11 (والإصدارات الأحدث).

  • في نظام Android 11، أول شاشة يتم الإبلاغ عنها أثناء التشغيل هي الشاشة الأساسية. نوع الاتصال (الداخلي مقابل الخارجي) غير مناسب. ومع ذلك، يظل من الصحيح عدم إمكانية فصل الشاشة الأساسية ومتابعة ما يلي: ينبغي أن يكون شاشة داخلية في الواقع. يُرجى ملاحظة أنّ بعض الهواتف القابلة للطيّ الشاشات الداخلية.
  • تم تصنيف شاشات العرض الثانوية بشكلٍ صحيح على أنّها Display.TYPE_INTERNAL. أو Display.TYPE_EXTERNAL (المعروف سابقًا باسم Display.TYPE_BUILT_IN) وDisplay.TYPE_HDMI على التوالي) حسب نوع الاتصال

التنفيذ

في الإصدار Android 9 والإصدارات الأقدم، يتم التعرّف على الشاشات من خلال أرقام تعريف 32 بت، حيث يشير الرقم 0 إلى الشاشة الداخلية، والرقم 1 هو الشاشة الخارجية، و[2, INT32_MAX] هي شاشات HWC الافتراضية، ويمثّل الرقم -1 شاشة عرض غير صالحة أو شاشة افتراضية غير تابعة لـ HWC.

بدءًا من نظام التشغيل Android 10، يتم توفير الشاشات بشكل ثابت. وأرقام التعريف الدائمة، ما يسمح بكل من SurfaceFlinger وDisplayManagerService لتتبع أكثر من شاشتي عرض والتعرف على الشاشات المعروضة من قبل. إذا كان HWC يتوافق مع IComposerClient.getDisplayIdentificationData ويوفّر إمكانية العرض بيانات التعريف، يحلّل SurfaceFlinger بنية EDID ويخصص قيمًا ثابتة معرّفات شاشات 64 بت لشاشات العرض المادية وHWC يتم التعبير عن المعرّفات باستخدام أحد أنواع الخيارات، حيث تمثل القيمة الفارغة عرضًا غير صالح أو نموذجًا افتراضيًا غير تابع لـ HWC العرض. بدون دعم HWC، يعود SurfaceFlinger إلى السلوك القديم مع معظم شاشتي عرض.

التركيز لكل عرض

لإتاحة العديد من مصادر الإدخال التي تستهدف شاشات فردية الوقت، يمكن ضبط Android 10 للتوافق مع العديد نافذة واحدة كحد أقصى لكل عرض. هذه المجموعة مخصَّصة فقط أنواع الأجهزة عندما يتفاعل عدة مستخدمين مع نفس الجهاز الوقت واستخدام أساليب أو أجهزة إدخال مختلفة، مثل Android السيارات.

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

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

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

استخدام "com.android.internal.R.bool.config_perDisplayFocusEnabled" لضبط التركيز لكل شاشة.

التوافق

المشكلة: في الإصدار 9 من نظام Android والإصدارات الأقدم، تظهر نافذة واحدة كحد أقصى في النظام في كل مرة.

الحل:في هذه الحالة النادرة، عندما تبدأ نافذتان من سيتم التركيز على العملية نفسها، سيركّز النظام على النافذة فقط أعلى في ترتيب Z. وقد تمت إزالة هذا الشرط من التطبيقات التي تستهدف Android 10، فمن المتوقع عندها أن يتمكنوا من دعم نوافذ متعددة يتم التركيز عليها في وقت واحد.

التنفيذ

يتحكّم WindowManagerService#mPerDisplayFocusEnabled في مدى توفر هذه الميزة. بعد ActivityManager، يتم استخدام ActivityDisplay#getFocusedStack() الآن بدلاً من العالمية التتبع في متغير. ActivityDisplay#getFocusedStack() التركيز بناءً على الترتيب Z بدلاً من التخزين المؤقت للقيمة. هذا حتى يحتاج مصدر واحد فقط، وهو WindowManager، إلى تتبع الترتيب Z للأنشطة.

يحصل ActivityStackSupervisor#getTopDisplayFocusedStack() على نهجًا مشابهًا لتلك الحالات عندما تكون الحزمة الأكثر تركيزًا في النظام . يتم اجتياز المكدسات من أعلى إلى أسفل، بحثًا عن أول حزمة مؤهلة.

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

يمكنك الاطّلاع على InputDispatcher::mFocusedWindowHandlesByDisplay و InputDispatcher::setFocusedDisplay() يتم أيضًا تحديث التطبيقات المركَّزة بشكل منفصل في ContentManagerService من خلال NativeInputManager::setFocusedApplication()

في WindowManager، يتم أيضًا تتبُّع النوافذ التي يتم التركيز عليها بشكل منفصل. يمكنك الاطّلاع على DisplayContent#mCurrentFocus و DisplayContent#mFocusedApp والاستخدامات ذات الصلة. تركيز ذو صلة حيث تم نقل طرق التتبع والتحديث من WindowManagerService إلى DisplayContent