एंड्रॉइड ऐप फ्रेमवर्क यूआई ऑब्जेक्ट्स के पदानुक्रम पर आधारित है जो व्यू से शुरू होता है। सभी यूआई तत्व माप की एक श्रृंखला और एक लेआउट प्रक्रिया से गुजरते हैं जो उन्हें एक आयताकार क्षेत्र में फिट करता है। फिर, सभी दृश्यमान दृश्य ऑब्जेक्ट को एक सतह पर प्रस्तुत किया जाता है जिसे विंडोमैनेजर द्वारा तब सेट किया गया था जब ऐप को अग्रभूमि में लाया गया था। ऐप का यूआई थ्रेड प्रति फ्रेम एक बफर में लेआउट और रेंडरिंग करता है।
भूतल दृश्य
सरफेस व्यू एक घटक है जिसका उपयोग आप अपने दृश्य पदानुक्रम के भीतर एक अतिरिक्त समग्र परत को एम्बेड करने के लिए कर सकते हैं। एक SurfaceView अन्य दृश्यों के समान लेआउट पैरामीटर लेता है, इसलिए इसे किसी भी अन्य दृश्य की तरह हेरफेर किया जा सकता है, लेकिन SurfaceView की सामग्री पारदर्शी होती है।
जब आप किसी बाहरी बफ़र स्रोत, जैसे जीएल संदर्भ या मीडिया डिकोडर के साथ प्रस्तुत करते हैं, तो आपको स्क्रीन पर बफ़र्स प्रदर्शित करने के लिए बफ़र्स स्रोत से बफ़र्स की प्रतिलिपि बनाने की आवश्यकता होती है। SurfaceView का उपयोग आपको ऐसा करने में सक्षम बनाता है।
जब SurfaceView का दृश्य घटक दृश्यमान होने वाला होता है, तो फ़्रेमवर्क SurfaceControl को SurfaceFlinger से एक नई सतह का अनुरोध करने के लिए कहता है। सतह के बनने या नष्ट होने पर कॉलबैक प्राप्त करने के लिए, SurfaceHolder इंटरफ़ेस का उपयोग करें। डिफ़ॉल्ट रूप से, नई बनाई गई सतह को ऐप यूआई सतह के पीछे रखा जाता है। आप नई सतह को शीर्ष पर रखने के लिए डिफ़ॉल्ट Z-ऑर्डरिंग को ओवरराइड कर सकते हैं।
SurfaceView के साथ रेंडर करना उन मामलों में फायदेमंद है जहां आपको एक अलग सतह पर रेंडर करने की आवश्यकता होती है, जैसे कि जब आप कैमरा एपीआई या ओपनजीएल ईएस संदर्भ के साथ रेंडर करते हैं। जब आप SurfaceView के साथ प्रस्तुत करते हैं, तो SurfaceFlinger सीधे स्क्रीन पर बफ़र्स बनाता है। सरफेस व्यू के बिना, आपको बफ़र्स को ऑफस्क्रीन सतह पर संयोजित करने की आवश्यकता होती है, जो फिर स्क्रीन पर मिश्रित हो जाती है, इसलिए सरफेस व्यू के साथ रेंडर करने से अतिरिक्त काम समाप्त हो जाता है। SurfaceView के साथ रेंडर करने के बाद, गतिविधि जीवनचक्र के साथ समन्वय करने के लिए UI थ्रेड का उपयोग करें और यदि आवश्यक हो तो दृश्य के आकार या स्थिति में समायोजन करें। फिर, हार्डवेयर कंपोज़र ऐप यूआई और अन्य परतों को मिश्रित करता है।
नई सतह बफ़रक्यू का निर्माता पक्ष है, जिसका उपभोक्ता सरफेसफ़्लिंगर परत है। आप किसी भी तंत्र के साथ सतह को अपडेट कर सकते हैं जो बफ़रक्यू को फ़ीड कर सकता है, जैसे कि सतह से आपूर्ति किए गए कैनवास फ़ंक्शंस, एक ईजीएलसरफेस संलग्न करना और जीएलईएस के साथ सतह पर ड्राइंग करना, या सतह को लिखने के लिए एक मीडिया डिकोडर को कॉन्फ़िगर करना।
SurfaceView और गतिविधि जीवनचक्र
SurfaceView का उपयोग करते समय, सतह को मुख्य UI थ्रेड के अलावा किसी अन्य थ्रेड से प्रस्तुत करें।
SurfaceView वाली किसी गतिविधि के लिए, दो अलग-अलग लेकिन अन्योन्याश्रित राज्य मशीनें हैं:
- ऐप
onCreate
/onResume
/onPause
- सतह बनाई/बदली/नष्ट कर दी गई
जब गतिविधि शुरू होती है, तो आपको इस क्रम में कॉलबैक मिलते हैं:
-
onCreate()
-
onResume()
-
surfaceCreated()
-
surfaceChanged()
यदि आप वापस क्लिक करते हैं, तो आपको मिलता है:
-
onPause()
-
surfaceDestroyed()
(सतह के ख़त्म होने से ठीक पहले बुलाया जाता है)
यदि आप स्क्रीन को घुमाते हैं, तो गतिविधि टूट जाती है और पुनः निर्मित हो जाती है और आपको पूरा चक्र मिल जाता है। आप isFinishing()
की जाँच करके बता सकते हैं कि यह एक त्वरित पुनरारंभ है। किसी गतिविधि को इतनी जल्दी शुरू/बंद करना संभव है कि surfaceCreated()
onPause()
के बाद हो।
यदि आप स्क्रीन को खाली करने के लिए पावर बटन को टैप करते हैं, तो आपको surfaceDestroyed()
के बिना केवल onPause()
मिलता है। सतह सक्रिय रहती है, और प्रतिपादन जारी रह सकता है। यदि आप उनसे अनुरोध करना जारी रखेंगे तो आपको कोरियोग्राफर इवेंट मिलते रहेंगे। यदि आपके पास एक लॉक स्क्रीन है जो एक अलग ओरिएंटेशन को मजबूर करती है, तो डिवाइस खाली होने पर आपकी गतिविधि फिर से शुरू हो सकती है। अन्यथा, आप पहले जैसी सतह के साथ स्क्रीन-रिक्त से बाहर आ सकते हैं।
धागे के जीवनकाल को सतह या गतिविधि से जोड़ा जा सकता है, यह इस बात पर निर्भर करता है कि स्क्रीन खाली होने पर आप क्या करना चाहते हैं। थ्रेड या तो एक्टिविटी स्टार्ट/स्टॉप पर या सतह पर निर्माण/नष्ट पर शुरू/बंद हो सकता है।
एक्टिविटी स्टार्ट/स्टॉप पर थ्रेड स्टार्ट/स्टॉप होना ऐप जीवनचक्र के साथ अच्छी तरह से काम करता है। आप रेंडरर थ्रेड को onResume()
में प्रारंभ करें और इसे onStop()
में रोकें। थ्रेड बनाते और कॉन्फ़िगर करते समय, कभी-कभी सतह पहले से मौजूद होती है, कभी-कभी यह नहीं होती है (उदाहरण के लिए, पावर बटन के साथ स्क्रीन को टॉगल करने के बाद भी यह सक्रिय है)। आपको धागे को आरंभ करने से पहले सतह बनने तक इंतजार करना होगा। आप surfaceCreate()
कॉलबैक को प्रारंभ नहीं कर सकते क्योंकि यदि सतह को दोबारा नहीं बनाया गया तो यह दोबारा सक्रिय नहीं होगा। इसके बजाय, सतह की स्थिति को क्वेरी या कैश करें, और इसे रेंडरर थ्रेड पर अग्रेषित करें।
थ्रेड को सतह पर शुरू/बंद करने से बनाना/नष्ट करना अच्छी तरह से काम करता है क्योंकि सतह और रेंडरर तार्किक रूप से आपस में जुड़े हुए हैं। सतह बनने के बाद आप थ्रेड शुरू करते हैं, जिससे कुछ इंटरथ्रेड संचार चिंताओं से बचा जा सकता है; और सतह पर निर्मित/बदले गए संदेश आसानी से अग्रेषित कर दिए जाते हैं। यह सुनिश्चित करने के लिए कि स्क्रीन खाली होने पर रेंडरिंग बंद हो जाती है और खाली न होने पर फिर से शुरू हो जाती है, कोरियोग्राफर को फ्रेम ड्रॉ कॉलबैक लागू करना बंद करने के लिए कहें। यदि रेंडरर थ्रेड चल रहा है तो onResume()
कॉलबैक फिर से शुरू करता है। हालाँकि, यदि आप फ़्रेम के बीच बीते समय के आधार पर एनिमेट करते हैं, तो अगली घटना आने से पहले एक बड़ा अंतर हो सकता है; एक स्पष्ट विराम/फिर से शुरू संदेश का उपयोग करने से इस समस्या का समाधान हो सकता है।
दोनों विकल्प, चाहे थ्रेड का जीवनकाल गतिविधि या सतह से जुड़ा हो, इस पर ध्यान केंद्रित करें कि रेंडरर थ्रेड कैसे कॉन्फ़िगर किया गया है और क्या यह निष्पादित हो रहा है। एक संबंधित चिंता गतिविधि समाप्त होने पर थ्रेड से स्थिति निकालने की है ( onStop()
या onSaveInstanceState()
में); ऐसे मामलों में, थ्रेड के जीवनकाल को गतिविधि से जोड़ना सबसे अच्छा काम करता है क्योंकि रेंडरर थ्रेड के शामिल होने के बाद, रेंडर किए गए थ्रेड की स्थिति को सिंक्रोनाइज़ेशन प्रिमिटिव के बिना एक्सेस किया जा सकता है।
GLSurface दृश्य
GLSurfaceView क्लास ईजीएल संदर्भों, इंटरथ्रेड संचार और गतिविधि जीवनचक्र के साथ इंटरैक्शन के प्रबंधन के लिए सहायक कक्षाएं प्रदान करता है। GLES का उपयोग करने के लिए आपको GLSurfaceView का उपयोग करने की आवश्यकता नहीं है।
उदाहरण के लिए, GLSurfaceView रेंडरिंग के लिए एक थ्रेड बनाता है और वहां एक EGL संदर्भ कॉन्फ़िगर करता है। गतिविधि रुकने पर स्थिति स्वचालित रूप से साफ़ हो जाती है। GLSurfaceView के साथ GLES का उपयोग करने के लिए अधिकांश ऐप्स को EGL के बारे में कुछ भी जानने की आवश्यकता नहीं है।
ज्यादातर मामलों में, GLSurfaceView GLES के साथ काम करना आसान बना सकता है। कुछ स्थितियों में, यह रास्ते में आ सकता है।