भूतल दृश्य और GLSurfaceView

एंड्रॉइड ऐप फ्रेमवर्क यूआई ऑब्जेक्ट्स के पदानुक्रम पर आधारित है जो व्यू से शुरू होता है। सभी UI तत्व माप की एक श्रृंखला और एक लेआउट प्रक्रिया से गुजरते हैं जो उन्हें एक आयताकार क्षेत्र में फिट करती है। फिर, सभी दृश्यमान दृश्य वस्तुओं को एक सतह पर प्रस्तुत किया जाता है जिसे WindowManager द्वारा तब स्थापित किया गया था जब ऐप को अग्रभूमि में लाया गया था। ऐप का यूआई थ्रेड प्रति फ्रेम एक बफर को लेआउट और प्रतिपादन करता है।

भूतल दृश्य

एक भूतल दृश्य एक घटक है जिसका उपयोग आप अपने दृश्य पदानुक्रम के भीतर एक अतिरिक्त समग्र परत को एम्बेड करने के लिए कर सकते हैं। एक SurfaceView अन्य दृश्यों के समान लेआउट पैरामीटर लेता है, इसलिए इसे किसी भी अन्य दृश्य की तरह हेरफेर किया जा सकता है, लेकिन SurfaceView की सामग्री पारदर्शी होती है।

जब आप बाहरी बफर स्रोत, जैसे जीएल संदर्भ या मीडिया डिकोडर के साथ प्रस्तुत करते हैं, तो आपको स्क्रीन पर बफर प्रदर्शित करने के लिए बफर स्रोत से बफर कॉपी करने की आवश्यकता होती है। सरफेस व्यू का उपयोग करने से आप ऐसा कर सकते हैं।

जब सरफेस व्यू का व्यू कंपोनेंट दिखाई देने वाला होता है, तो फ्रेमवर्क सरफेसकंट्रोल को सरफेसफ्लिंगर से एक नई सतह का अनुरोध करने के लिए कहता है। सतह के बनने या नष्ट होने पर कॉलबैक प्राप्त करने के लिए, SurfaceHolder इंटरफ़ेस का उपयोग करें। डिफ़ॉल्ट रूप से, नई बनाई गई सतह को ऐप UI सतह के पीछे रखा जाता है। नई सतह को शीर्ष पर रखने के लिए आप डिफ़ॉल्ट Z- क्रम को ओवरराइड कर सकते हैं।

सरफेस व्यू के साथ रेंडरिंग उन मामलों में फायदेमंद है जहां आपको एक अलग सतह पर रेंडर करने की आवश्यकता होती है, जैसे कि जब आप कैमरा एपीआई या ओपनजीएल ईएस संदर्भ के साथ प्रस्तुत करते हैं। जब आप SurfaceView के साथ रेंडर करते हैं, तो SurfaceFlinger स्क्रीन पर सीधे बफ़र्स की रचना करता है। सरफेस व्यू के बिना, आपको बफ़र्स को एक ऑफस्क्रीन सतह पर संयोजित करने की आवश्यकता होती है, जो तब स्क्रीन पर कंपोजिट हो जाती है, इसलिए सर्फेस व्यू के साथ रेंडर करने से अतिरिक्त काम खत्म हो जाता है। सर्फेस व्यू के साथ प्रस्तुत करने के बाद, गतिविधि जीवनचक्र के साथ समन्वय करने के लिए यूआई थ्रेड का उपयोग करें और यदि आवश्यक हो तो दृश्य के आकार या स्थिति में समायोजन करें। फिर, हार्डवेयर कम्पोज़र ऐप UI और अन्य परतों को मिश्रित करता है।

नई सतह बफ़रक्यू का निर्माता पक्ष है, जिसका उपभोक्ता सरफेसफ्लिंगर परत है। आप किसी भी तंत्र के साथ सतह को अपडेट कर सकते हैं जो बफरक्यू को खिला सकता है, जैसे सतह-आपूर्ति वाले कैनवास फ़ंक्शन, एक ईजीएलसर्फेस संलग्न करना और जीएलईएस के साथ सतह पर ड्राइंग, या सतह को लिखने के लिए मीडिया डिकोडर को कॉन्फ़िगर करना।

भूतल दृश्य और गतिविधि जीवनचक्र

सरफेस व्यू का उपयोग करते समय, मुख्य यूआई थ्रेड के अलावा किसी अन्य थ्रेड से सतह को रेंडर करें।

भूतल दृश्य वाली गतिविधि के लिए, दो अलग-अलग लेकिन अन्योन्याश्रित राज्य मशीनें हैं:

  • ऐप onCreate / onResume / ऑन onPause
  • सतह बनाई/बदली/नष्ट

जब गतिविधि शुरू होती है, तो आपको इस क्रम में कॉलबैक मिलते हैं:

  1. onCreate()
  2. onResume()
  3. surfaceCreated()
  4. surfaceChanged()

यदि आप वापस क्लिक करते हैं, तो आपको मिलता है:

  1. onPause()
  2. surfaceDestroyed() (सतह दूर होने से ठीक पहले कहा जाता है)

यदि आप स्क्रीन को घुमाते हैं, तो गतिविधि टूट जाती है और फिर से बनाई जाती है और आपको पूरा चक्र मिलता है। आप isFinishing() को चेक करके बता सकते हैं कि यह एक त्वरित पुनरारंभ है। किसी गतिविधि को इतनी जल्दी शुरू/बंद करना संभव है कि surfaceCreated() onPause() के बाद होता है।

यदि आप स्क्रीन को खाली करने के लिए पावर बटन को टैप करते हैं, तो आपको केवल onPause() बिना surfaceDestroyed() प्राप्त होता है। सतह सक्रिय रहती है, और प्रतिपादन जारी रह सकता है। यदि आप उनसे अनुरोध करना जारी रखते हैं तो आप कोरियोग्राफर ईवेंट प्राप्त करना जारी रख सकते हैं। यदि आपके पास एक लॉक स्क्रीन है जो एक अलग अभिविन्यास को बाध्य करती है, तो डिवाइस खाली होने पर आपकी गतिविधि फिर से शुरू हो सकती है। अन्यथा, आप पहले जैसी ही सतह के साथ स्क्रीन-रिक्त से बाहर आ सकते हैं।

स्क्रीन के खाली होने पर आप क्या करना चाहते हैं, इस पर निर्भर करते हुए, थ्रेड के जीवनकाल को सतह या गतिविधि से जोड़ा जा सकता है। थ्रेड गतिविधि प्रारंभ/बंद या सतह पर बनाने/नष्ट करने पर या तो प्रारंभ/रोक सकता है।

एक्टिविटी स्टार्ट/स्टॉप पर थ्रेड स्टार्ट/स्टॉप ऐप लाइफसाइकिल के साथ अच्छी तरह से काम करता है। आप रेंडरर थ्रेड को onResume() में प्रारंभ करते हैं और इसे onStop() में रोकते हैं। थ्रेड बनाते और कॉन्फ़िगर करते समय, कभी-कभी सतह पहले से मौजूद होती है, कभी-कभी ऐसा नहीं होता है (उदाहरण के लिए, पावर बटन के साथ स्क्रीन को चालू करने के बाद भी यह सक्रिय रहता है)। थ्रेड में इनिशियलाइज़ करने से पहले आपको सतह के बनने का इंतज़ार करना होगा। आप surfaceCreate() कॉलबैक में इनिशियलाइज़ नहीं कर सकते हैं क्योंकि अगर सतह को फिर से नहीं बनाया गया तो यह फिर से फायर नहीं करेगा। इसके बजाय, सतह की स्थिति को क्वेरी या कैश करें, और इसे रेंडरर थ्रेड पर अग्रेषित करें।

सतह पर थ्रेड स्टार्ट/स्टॉप बनाने/नष्ट करने से अच्छी तरह से काम करता है क्योंकि सतह और रेंडरर तार्किक रूप से जुड़े हुए हैं। सतह बनने के बाद आप थ्रेड शुरू करते हैं, जो कुछ इंटरथ्रेड संचार चिंताओं से बचा जाता है; और सतह निर्मित/बदले गए संदेशों को केवल अग्रेषित किया जाता है। यह सुनिश्चित करने के लिए कि स्क्रीन के खाली होने पर रेंडरिंग रुक जाती है और खाली होने पर फिर से शुरू हो जाती है, कोरियोग्राफर से कहें कि वह फ्रेम ड्रॉ कॉलबैक का आह्वान करना बंद कर दे। यदि रेंडरर थ्रेड चल रहा है तो onResume() कॉलबैक को फिर से शुरू करता है। हालांकि, यदि आप फ़्रेम के बीच बीता हुआ समय के आधार पर एनिमेट करते हैं, तो अगला ईवेंट आने से पहले एक बड़ा अंतर हो सकता है; एक स्पष्ट विराम/फिर से शुरू संदेश का उपयोग करके इस समस्या को हल किया जा सकता है।

दोनों विकल्प, चाहे थ्रेड का जीवनकाल गतिविधि या सतह से जुड़ा हो, इस बात पर ध्यान केंद्रित करें कि रेंडरर थ्रेड कैसे कॉन्फ़िगर किया गया है और क्या यह निष्पादित हो रहा है। एक संबंधित चिंता थ्रेड से राज्य निकाल रही है जब गतिविधि समाप्त हो जाती है ( onStop() या onSaveInstanceState() में); ऐसे मामलों में, थ्रेड के जीवनकाल को गतिविधि से बांधना सबसे अच्छा काम करता है क्योंकि रेंडरर थ्रेड के जुड़ने के बाद, रेंडर किए गए थ्रेड की स्थिति को बिना सिंक्रोनाइज़ेशन प्रिमिटिव के एक्सेस किया जा सकता है।

जीएलसर्फेस व्यू

GLSurfaceView वर्ग ईजीएल संदर्भों, इंटरथ्रेड संचार और गतिविधि जीवनचक्र के साथ बातचीत के प्रबंधन के लिए सहायक कक्षाएं प्रदान करता है। GLES का उपयोग करने के लिए आपको GLSurfaceView का उपयोग करने की आवश्यकता नहीं है।

उदाहरण के लिए, GLSurfaceView एक ईजीएल संदर्भ को प्रस्तुत करने और कॉन्फ़िगर करने के लिए एक थ्रेड बनाता है। गतिविधि रुकने पर राज्य अपने आप साफ हो जाता है। अधिकांश ऐप्स को GLSurfaceView के साथ GLES का उपयोग करने के लिए EGL के बारे में कुछ भी जानने की आवश्यकता नहीं है।

ज्यादातर मामलों में, GLSurfaceView GLES के साथ काम करना आसान बना सकता है। कुछ स्थितियों में, यह रास्ते में आ सकता है।