تستند واجهة مستخدم إطار عمل تطبيقات Android إلى تسلسل هرمي للكائنات التي تبدأ بعرض. تخضع جميع عناصر واجهة المستخدم لمجموعة من القياسات وعملية تنسيق تناسبها في منطقة مستطيلة. بعد ذلك، يتم عرض كل عناصر الاطِّلاع المرئية على سطح تم إعداده من قِبل ملف برمجي WindowManager عند عرض التطبيق في المقدّمة. ينفِّذ مؤشر تسلسل واجهة المستخدم في التطبيق التخطيط والعرض في ذاكرة تخزين مؤقت لكل إطار.
SurfaceView
SurfaceView هو مكوّن يمكنك استخدامه لتضمين طبقة مركبة إضافية ضمن التدرّج الهرمي لطريقة العرض. تستخدِم واجهة SurfaceView مَعلمات التنسيق نفسها المستخدَمة في الواجهات الأخرى، لذا يمكن التلاعب بها مثل أي واجهة أخرى، ولكن تكون محتويات واجهة SurfaceView شفافة.
عند العرض باستخدام مصدر مخزن مؤقت خارجي، مثل سياق GL أو فك ترميز وسائط، عليك نسخ المخزن المؤقت من مصدر المخزن المؤقت لعرض المخزن المؤقت على الشاشة. يتيح لك استخدام SurfaceView إجراء ذلك.
عندما يكون مكوّن عرض SurfaceView على وشك أن يصبح مرئيًا، يطلب الإطار من SurfaceControl طلب سطح جديد من SurfaceFlinger. لتلقّي طلبات إعادة الاتصال عند إنشاء السطح أو إزالته، استخدِم واجهة SurfaceHolder. يتم تلقائيًا وضع المساحة التي تم إنشاؤها حديثًا خلف مساحة واجهة مستخدم التطبيق. يمكنك إلغاء الترتيب التلقائي للمحور Z لوضع السطح الجديد في الأعلى.
يكون التقديم باستخدام SurfaceView مفيدًا في الحالات التي تحتاج فيها إلى التقديم على سطح منفصل، مثل عند التقديم باستخدام Camera API أو سياق OpenGL ES. عند العرض باستخدام SurfaceView، يُنشئ SurfaceFlinger ملفًا مؤقتًا للعرض على الشاشة مباشرةً. بدون SurfaceView، عليك دمج المخازن المؤقتة في سطح خارج الشاشة، ثم دمجها في الشاشة، لذا يؤدي التقديم باستخدام SurfaceView إلى إزالة العمل الإضافي. بعد المعالجة باستخدام SurfaceView، استخدِم سلسلة مهام واجهة المستخدم للتنسيق مع دورة حياة النشاط وإجراء تعديلات على حجم العرض أو موضعه إذا لزم الأمر. بعد ذلك، يمزج "أداة إنشاء الأجهزة" واجهة مستخدم التطبيق والطبقات الأخرى.
السطح الجديد هو الجانب المُنشئ لواجهة BufferQueue، ويكون المستخدِم هو طبقة SurfaceFlinger. يمكنك تعديل مساحة العرض باستخدام أي آلية يمكنها إدخال BufferQueue، مثل وظائف Canvas المقدَّمة من مساحة العرض، أو إرفاق سطح EGLSurface والرسم على السطح باستخدام GLES، أو ضبط وحدة فك ترميز وسائط لكتابة مساحة العرض.
SurfaceView ومراحل النشاط
عند استخدام SurfaceView، يمكنك عرض السطح من سلسلة مهام أخرى غير سلسلة مهام واجهة المستخدم الرئيسية.
بالنسبة إلى النشاط الذي يتضمّن SurfaceView، هناك سلسلتَان من الحالات المنفصلتان ولكنهما مترابطتان:
- التطبيق
onCreate
/onResume
/onPause
- سطح تم إنشاؤه أو تغييره أو إزالته
عند بدء النشاط، ستتلقّى مكالمات استرجاعية بالترتيب التالي:
onCreate()
onResume()
surfaceCreated()
surfaceChanged()
إذا نقرت على "رجوع"، ستظهر لك الخيارات التالية:
onPause()
surfaceDestroyed()
(يتمّ استدعاؤه قبل اختفاء السطح مباشرةً)
في حال تدوير الشاشة، يتم تفكيك النشاط وإعادة إنشائه، وبذلك تتمكّن من تنفيذ الدورة الكاملة. يمكنك معرفة أنّه سيتم إجراء إعادة تشغيل سريعة من خلال وضع علامة في المربّع بجانب isFinishing()
. من الممكن بدء نشاط أو إيقافه ببطء شديد بحيث يحدث surfaceCreated()
بعد
onPause()
.
إذا نقرت على زر التشغيل لإيقاف الشاشة، ستظهر لك علامة
onPause()
فقط بدون surfaceDestroyed()
. تظل المساحة
نشطة، ويمكن مواصلة العرض. يمكنك مواصلة تلقّي
أحداث مصمّمي الرقص إذا واصلت طلبها. إذا كان لديك شاشة قفل تفرض اتجاهًا مختلفًا، قد تتم إعادة تشغيل نشاطك عند إزالة الشاشة المظلمة عن الشاشة. بخلاف ذلك، يمكنك الخروج من وضع "شاشة فارغة" باستخدام سطح الشاشة نفسه كما في السابق.
يمكن ربط مدة صلاحية سلسلة المحادثات بالسطح أو بالنشاط، استنادًا إلى ما تريد أن يحدث عندما تصبح الشاشة فارغة. يمكن بدء/إيقاف سلسلة المهام إما عند بدء/إيقاف النشاط أو عند إنشاء/إتلاف السطح.
إنّ بدء/إيقاف سلسلة المهام عند بدء/إيقاف النشاط يعمل بشكل جيد مع دورة حياة التطبيق. يمكنك بدء سلسلة المهام الخاصة بوحدة العرض
في onResume()
وإيقافها في onStop()
.
عند إنشاء سلسلة المحادثات وضبطها، يكون سطح العرض
متوفّرًا في بعض الأحيان، وفي أحيان أخرى لا يكون (على سبيل المثال، يظل نشطًا بعد تبديل
الشاشة باستخدام زر التشغيل). عليك الانتظار إلى أن يتم إنشاء السطح
قبل الإعداد في سلسلة المحادثات. لا يمكنك الإعداد في callback
surfaceCreate()
لأنّه لن يتم تشغيله مرة أخرى إذا لم يتم إعادة إنشاء سطح الشاشة. بدلاً من ذلك، يمكنك طلب حالة سطح الادراج أو تخزينها مؤقتًا، ثم إعادة توجيهها إلى سلسلة مهام أداة التقديم.
يعمل بدء/إيقاف سلسلة التعليمات عند إنشاء/إتلاف السطح بشكل جيد لأنّه
يكون السطح وبرنامج التقديم ملتصقين منطقيًا
ببعضهما. يمكنك بدء سلسلة المحادثات بعد إنشاء السطح، ما يؤدي إلى اجتناب بعض المشاكل المتعلّقة بالتواصل بين سلاسل المحادثات، ويتم إعادة توجيه الرسائل التي تم إنشاؤها أو تغييرها في السطح. لضمان توقُّف العرض عند تغيُّر الشاشة
إلى اللون الأبيض واستئنافه عند عودتها إلى اللون العادي، اطلب من Choreographer إيقاف استدعاء
الاستدعاء المرتبط برسم اللقطة. يستأنف onResume()
عمليات الاستدعاء إذا كان مؤشر تسلسل معالجة العروض قيد التشغيل. ومع ذلك، إذا كنت تضيف تأثيرًا متحركًا
استنادًا إلى الوقت المنقضي بين اللقطات، قد تَظهر فجوة كبيرة قبل أن يبدأ
الحدث التالي. ويمكن حلّ هذه المشكلة باستخدام رسالة واضحة للتوقف المؤقت أو الاستئناف.
يركز كلا الخيارَين، سواء كان عمر سلسلة المهام مرتبطًا بالنشاط
أو السطح، على كيفية برمجة سلسلة المهام لعرض الرسومات
وما إذا كانت يتم تنفيذها. ومن المخاوف ذات الصلة استخراج الحالة
من سلسلة المهام عند إنهاء النشاط (في onStop()
أو
onSaveInstanceState()
). وفي هذه الحالات، يكون ربط مدة حياة
سلسلة المهام بالنشاط هو الخيار الأفضل لأنّه
بعد الانضمام إلى سلسلة مهام العرض، يمكن الوصول إلى حالة
سلسلة المهام المعروضة بدون استخدام العناصر الأساسية للمزامنة.
GLSurfaceView
توفّر فئة GLSurfaceView فئات مساعدة لإدارة سياقات EGL، والتواصل بين الخيوط، والتفاعل مع دورة حياة النشاط. لست بحاجة إلى استخدام GLSurfaceView لاستخدام GLES.
على سبيل المثال، تنشئ GLSurfaceView سلسلة مهام لعرض المحتوى وتضبط سياق EGL هناك. يتمّ تنظيف الحالة تلقائيًا عند إيقاف النشاط مؤقتًا. لا تحتاج معظم التطبيقات إلى معرفة أي شيء عن EGL لاستخدام GLES مع GLSurfaceView.
في معظم الحالات، يمكن أن يسهّل GLSurfaceView استخدام GLES. وفي بعض الحالات، قد يتسبب ذلك في حدوث مشاكل.