सिद्धांत और Jetpack Compose का इस्तेमाल
Android 3.0 (एपीआई लेवल 11) से, Android 2D रेंडरिंग पाइपलाइन में हार्डवेयर से तेज़ी लाने की सुविधा काम करती है. इसका मतलब है कि View के कैनवस पर किए जाने वाले सभी ड्रॉइंग ऑपरेशन, जीपीयू का इस्तेमाल करते हैं.
हार्डवेयर ऐक्सलरेशन को चालू करने के लिए, ज़्यादा संसाधनों की ज़रूरत होती है. इसलिए, आपका ऐप्लिकेशन ज़्यादा रैम का इस्तेमाल करेगा.
अगर आपका टारगेट एपीआई लेवल >=14 है, तो हार्डवेयर से तेज़ी लाने की सुविधा डिफ़ॉल्ट रूप से चालू होती है. हालांकि, इसे साफ़ तौर पर भी चालू किया जा सकता है. अगर आपका ऐप्लिकेशन सिर्फ़ स्टैंडर्ड व्यू और Drawable का इस्तेमाल करता है, तो इसे सभी के लिए चालू करने से, ड्रॉइंग पर कोई बुरा असर नहीं पड़ेगा. हालांकि, 2D ड्राइंग के सभी ऑपरेशनों के लिए, हार्डवेयर ऐक्सेलरेट करने की सुविधा काम नहीं करती. इसलिए, इसे चालू करने से आपके कुछ कस्टम व्यू या ड्राइंग कॉल पर असर पड़ सकता है. समस्याएं आम तौर पर, न दिखने वाले एलिमेंट, अपवाद या गलत तरीके से रेंडर किए गए पिक्सल के तौर पर दिखती हैं. इस समस्या को ठीक करने के लिए, Android आपको कई लेवल पर हार्डवेयर से तेज़ी लाने की सुविधा को चालू या बंद करने का विकल्प देता है. हार्डवेयर से तेज़ी लाने की सुविधा को कंट्रोल करना लेख पढ़ें.
अगर आपका ऐप्लिकेशन कस्टम ड्राइंग करता है, तो अपने ऐप्लिकेशन को हार्डवेयर से तेज़ी लाने की सुविधा चालू करके, असली हार्डवेयर डिवाइसों पर टेस्ट करें. इससे आपको किसी भी समस्या का पता लगाने में मदद मिलेगी. ड्राइंग ऑपरेशन के लिए सहायता सेक्शन में, हार्डवेयर की मदद से तेज़ी लाने की सुविधा से जुड़ी ज्ञात समस्याओं के बारे में बताया गया है. साथ ही, उन्हें हल करने का तरीका भी बताया गया है.
फ़्रेमवर्क एपीआई के साथ OpenGL और Renderscript भी देखें.
हार्डवेयर की मदद से तेज़ी लाने की सुविधा को कंट्रोल करना
हार्डवेयर से तेज़ी लाने की सुविधा को इन लेवल पर कंट्रोल किया जा सकता है:
- ऐप्लिकेशन
- गतिविधि
- विंडो
- देखें
ऐप्लिकेशन लेवल
अपने पूरे ऐप्लिकेशन के लिए हार्डवेयर ऐक्सेलरेटेड रेंडरिंग की सुविधा चालू करने के लिए, अपनी Android मेनिफ़ेस्ट फ़ाइल में <application> टैग में यह एट्रिब्यूट जोड़ें:
<application android:hardwareAccelerated="true" ...>
गतिविधि का लेवल
अगर हार्डवेयर ऐक्सलरेशन को ग्लोबल लेवल पर चालू करने पर, आपका ऐप्लिकेशन ठीक से काम नहीं करता है, तो इसे अलग-अलग गतिविधियों के लिए भी कंट्रोल किया जा सकता है. गतिविधि के लेवल पर हार्डवेयर से तेज़ी लाने की सुविधा को चालू या बंद करने के लिए, <activity> एलिमेंट के लिए android:hardwareAccelerated एट्रिब्यूट का इस्तेमाल किया जा सकता है. यहां दिए गए उदाहरण में, पूरे ऐप्लिकेशन के लिए हार्डवेयर की मदद से तेज़ी लाने की सुविधा चालू की गई है. हालांकि, इसे एक ऐक्टिविटी के लिए बंद कर दिया गया है:
<application android:hardwareAccelerated="true">
<activity ... />
<activity android:hardwareAccelerated="false" />
</application>
विंडो लेवल
अगर आपको ज़्यादा कंट्रोल की ज़रूरत है, तो यहां दिए गए कोड की मदद से, किसी विंडो के लिए हार्डवेयर से तेज़ी लाने की सुविधा चालू की जा सकती है:
Kotlin
window.setFlags( WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED )
Java
getWindow().setFlags( WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
व्यू लेवल
रनटाइम के दौरान किसी व्यू के लिए, हार्डवेयर ऐक्सेलरेट की सुविधा बंद की जा सकती है. इसके लिए, यहां दिया गया कोड इस्तेमाल करें:
Kotlin
myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null)
Java
myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
यह पता लगाना कि कोई व्यू, हार्डवेयर की मदद से तेज़ी से रेंडर किया गया है या नहीं
कभी-कभी किसी ऐप्लिकेशन के लिए यह जानना ज़रूरी होता है कि वह फ़िलहाल हार्डवेयर ऐक्सेलरेटेड है या नहीं. खास तौर पर, कस्टम व्यू जैसी चीज़ों के लिए. अगर आपका ऐप्लिकेशन, कस्टम ड्राइंग की सुविधा का इस्तेमाल करता है और नई रेंडरिंग पाइपलाइन, सभी कार्रवाइयों के साथ काम नहीं करती है, तो यह विकल्प आपके लिए खास तौर पर फ़ायदेमंद है.
यह देखने के दो तरीके हैं कि ऐप्लिकेशन में हार्डवेयर ऐक्सेलरेटेड रेंडरिंग की सुविधा चालू है या नहीं:
अगर
Viewको हार्डवेयर की मदद से तेज़ी लाने की सुविधा वाली विंडो से अटैच किया जाता है, तोView.isHardwareAcceleratedtrueदिखाता है.अगर
Canvasको हार्डवेयर की मदद से तेज़ी से प्रोसेस किया जाता है, तोCanvas.isHardwareAccelerated,trueदिखाता है.
अगर आपको अपने ड्रॉइंग कोड में यह जांच करनी है, तो जब भी हो सके, View.isHardwareAccelerated के बजाय Canvas.isHardwareAccelerated का इस्तेमाल करें. जब किसी व्यू को हार्डवेयर की मदद से रेंडर की गई विंडो से अटैच किया जाता है, तब भी उसे हार्डवेयर की मदद से रेंडर न किए गए कैनवस का इस्तेमाल करके बनाया जा सकता है. उदाहरण के लिए, ऐसा तब होता है, जब कैश मेमोरी में सेव करने के लिए किसी व्यू को बिटमैप में बदला जाता है.
Android के ड्रॉइंग मॉडल
हार्डवेयर से तेज़ी लाने की सुविधा चालू होने पर, Android फ़्रेमवर्क एक नए ड्राइंग मॉडल का इस्तेमाल करता है. यह मॉडल, आपकी स्क्रीन पर ऐप्लिकेशन को रेंडर करने के लिए डिसप्ले लिस्ट का इस्तेमाल करता है. डिस्प्ले लिस्ट और आपके ऐप्लिकेशन पर उनके असर को पूरी तरह से समझने के लिए, यह जानना ज़रूरी है कि Android, हार्डवेयर ऐक्सलरेशन के बिना व्यू कैसे दिखाता है. यहां दिए गए सेक्शन में, सॉफ़्टवेयर पर आधारित और हार्डवेयर की मदद से तेज़ किए गए ड्रॉइंग मॉडल के बारे में बताया गया है.
सॉफ़्टवेयर पर आधारित ड्रॉइंग मॉडल
सॉफ़्टवेयर ड्राइंग मॉडल में, व्यू इन दो चरणों में बनाए जाते हैं:
- हैरारकी को अमान्य करना
- हैरारकी बनाना
जब किसी ऐप्लिकेशन को अपने यूज़र इंटरफ़ेस (यूआई) के किसी हिस्से को अपडेट करना होता है, तो वह उस व्यू पर invalidate() (या इसके किसी एक वैरिएंट) को लागू करता है जिसमें बदलाव किया गया है. अमान्य होने के मैसेज, व्यू हैरारकी में सबसे ऊपर तक भेजे जाते हैं. इससे स्क्रीन के उन हिस्सों का पता चलता है जिन्हें फिर से रेंडर करना होता है (डर्टी रीजन). इसके बाद, Android सिस्टम हैरारकी में मौजूद उस व्यू को दिखाता है जो डर्टी रीजन के साथ इंटरसेक्ट करता है. अफ़सोस की बात है कि इस ड्राइंग मॉडल की दो कमियां हैं:
पहला, इस मॉडल को हर ड्रॉ पास पर बहुत सारे कोड को लागू करने की ज़रूरत होती है. उदाहरण के लिए, अगर आपका ऐप्लिकेशन किसी बटन पर
invalidateको कॉल करता है और वह बटन किसी दूसरे व्यू के ऊपर है, तो Android सिस्टम व्यू को फिर से रेंडर करता है. भले ही, उसमें कोई बदलाव न हुआ हो.दूसरी समस्या यह है कि ड्राइंग मॉडल, आपके ऐप्लिकेशन में मौजूद गड़बड़ियों को छिपा सकता है. Android सिस्टम, डर्टी रीजन के इंटरसेक्ट होने पर व्यू को फिर से ड्रॉ करता है. इसलिए, जिस व्यू के कॉन्टेंट में आपने बदलाव किया है उसे फिर से ड्रॉ किया जा सकता है. भले ही, उस पर
invalidateको कॉल न किया गया हो. ऐसा होने पर, आपको सही तरीके से काम करने के लिए, किसी दूसरे व्यू के अमान्य होने पर निर्भर रहना पड़ता है. ऐप्लिकेशन में बदलाव करने पर, यह व्यवहार बदल सकता है. इसलिए, जब भी डेटा में बदलाव किया जाता है या व्यू के ड्राइंग कोड पर असर डालने वाली स्थिति में बदलाव किया जाता है, तब आपको हमेशा अपने कस्टम व्यू परinvalidateको कॉल करना चाहिए.
हार्डवेयर की मदद से ड्रॉइंग की रफ़्तार बढ़ाने वाला मॉडल
Android सिस्टम अब भी स्क्रीन अपडेट का अनुरोध करने और व्यू रेंडर करने के लिए, invalidate और draw का इस्तेमाल करता है. हालांकि, यह ड्रॉइंग को अलग तरीके से हैंडल करता है.
ड्रॉइंग के निर्देशों को तुरंत लागू करने के बजाय, Android सिस्टम उन्हें डिसप्ले लिस्ट में रिकॉर्ड करता है. डिसप्ले लिस्ट में, व्यू हाइरार्की के ड्रॉइंग कोड का आउटपुट होता है. एक और ऑप्टिमाइज़ेशन यह है कि Android सिस्टम को सिर्फ़ उन व्यू के लिए डिसप्ले सूचियां रिकॉर्ड और अपडेट करनी होती हैं जिन्हें invalidate कॉल से डर्टी के तौर पर मार्क किया गया है. जिन व्यू को अमान्य नहीं किया गया है उन्हें फिर से बनाया जा सकता है. इसके लिए, पहले से रिकॉर्ड की गई डिसप्ले लिस्ट को फिर से जारी करें. नए ड्राइंग मॉडल में तीन चरण होते हैं:
हैरारकी को अमान्य करना
डिस्प्ले लिस्ट को रिकॉर्ड और अपडेट करना
डिसप्ले लिस्ट बनाना
इस मॉडल में, गंदे क्षेत्र को इंटरसेक्ट करने वाले व्यू पर भरोसा नहीं किया जा सकता, ताकि उसके draw तरीके को लागू किया जा सके. यह पक्का करने के लिए कि Android सिस्टम, व्यू की डिसप्ले लिस्ट रिकॉर्ड करे, आपको invalidate को कॉल करना होगा. ऐसा न करने पर, बदलाव करने के बाद भी व्यू एक जैसा दिखता है.
डिसप्ले सूचियों का इस्तेमाल करने से, ऐनिमेशन की परफ़ॉर्मेंस भी बेहतर होती है. ऐसा इसलिए, क्योंकि ऐल्फ़ा या रोटेशन जैसी कुछ प्रॉपर्टी सेट करने के लिए, टारगेट किए गए व्यू को अमान्य करने की ज़रूरत नहीं होती. यह काम अपने-आप हो जाता है. यह ऑप्टिमाइज़ेशन, डिसप्ले लिस्ट वाले व्यू पर भी लागू होता है. डिसप्ले लिस्ट वाला कोई भी व्यू तब दिखता है, जब आपका ऐप्लिकेशन हार्डवेयर ऐक्सेलरेटेड हो. उदाहरण के लिए, मान लें कि एक LinearLayout है, जिसमें Button के ऊपर एक ListView है. LinearLayout के लिए डिसप्ले लिस्ट ऐसी दिखती है:
DrawDisplayList(ListView)DrawDisplayList(Button)
मान लें कि अब आपको ListView की अपारदर्शिता बदलनी है. ListView पर setAlpha(0.5f) को लागू करने के बाद, अब डिसप्ले लिस्ट में यह शामिल है:
SaveLayerAlpha(0.5)DrawDisplayList(ListView)RestoreDrawDisplayList(Button)
ListView का जटिल ड्राइंग कोड नहीं चलाया गया. इसके बजाय, सिस्टम ने सिर्फ़ LinearLayout की डिसप्ले लिस्ट को अपडेट किया.
जिस ऐप्लिकेशन में हार्डवेयर ऐक्सेलरेटेड रेंडरिंग की सुविधा चालू नहीं होती है उसमें सूची और उसके पैरंट, दोनों के ड्रॉइंग कोड को फिर से एक्ज़ीक्यूट किया जाता है.
ड्रॉ करने की कार्रवाइयों के लिए सहायता
हार्डवेयर की मदद से रेंडर किए जाने पर, 2D रेंडरिंग पाइपलाइन, Canvas ड्राइंग के सबसे ज़्यादा इस्तेमाल किए जाने वाले ऑपरेशन के साथ-साथ, कम इस्तेमाल किए जाने वाले कई ऑपरेशन भी सपोर्ट करती है. Android के साथ शिप किए गए ऐप्लिकेशन, डिफ़ॉल्ट विजेट, लेआउट, और सामान्य तौर पर इस्तेमाल होने वाले बेहतर विज़ुअल इफ़ेक्ट, जैसे कि रिफ़्लेक्शन और टाइल वाली बनावट को रेंडर करने के लिए इस्तेमाल की जाने वाली सभी ड्रॉइंग कार्रवाइयां काम करती हैं.
यहां दी गई टेबल में, एपीआई के अलग-अलग लेवल पर, अलग-अलग कार्रवाइयों के लिए सहायता के लेवल के बारे में बताया गया है:
| एपीआई का पहला लेवल | ||||
| कैनवस | ||||
| drawBitmapMesh() (colors array) | 18 | |||
| drawPicture() | 23 | |||
| drawPosText() | 16 | |||
| drawTextOnPath() | 16 | |||
| drawVertices() | 29 | |||
| setDrawFilter() | 16 | |||
| clipPath() | 18 | |||
| clipRegion() | 18 | |||
| clipRect(Region.Op.XOR) | 18 | |||
| clipRect(Region.Op.Difference) | 18 | |||
| clipRect(Region.Op.ReverseDifference) | 18 | |||
| रोटेशन/पर्सपेक्टिव के साथ clipRect() | 18 | |||
| पेंट | ||||
| setAntiAlias() (टेक्स्ट के लिए) | 18 | |||
| setAntiAlias() (लाइनों के लिए) | 16 | |||
| setFilterBitmap() | 17 | |||
| setLinearText() | ✗ | |||
| setMaskFilter() | ✗ | |||
| setPathEffect() (लाइनें बनाने के लिए) | 28 | |||
| setShadowLayer() (टेक्स्ट के अलावा) | 28 | |||
| setStrokeCap() (लाइनों के लिए) | 18 | |||
| setStrokeCap() (पॉइंट के लिए) | 19 | |||
| setSubpixelText() | 28 | |||
| Xfermode | ||||
| PorterDuff.Mode.DARKEN (framebuffer) | 28 | |||
| PorterDuff.Mode.LIGHTEN (फ़्रेमबफ़र) | 28 | |||
| PorterDuff.Mode.OVERLAY (फ़्रेमबफ़र) | 28 | |||
| शेडर | ||||
| ComposeShader के अंदर ComposeShader | 28 | |||
| ComposeShader में एक ही तरह के शेडर | 28 | |||
| ComposeShader पर लोकल मैट्रिक्स | 18 | |||
कैनवस को स्केल करना
हार्डवेयर की मदद से तेज़ की गई 2D रेंडरिंग पाइपलाइन को सबसे पहले, बिना स्केल किए ड्राइंग करने की सुविधा देने के लिए बनाया गया था. इसमें कुछ ड्राइंग ऑपरेशन, ज़्यादा स्केल वैल्यू पर क्वालिटी को काफ़ी हद तक कम कर देते हैं. इन कार्रवाइयों को, स्केल 1.0 पर बनाए गए टेक्सचर के तौर पर लागू किया जाता है. इन्हें जीपीयू से बदला जाता है. एपीआई लेवल 28 से, ड्रॉइंग से जुड़ी सभी कार्रवाइयों को बिना किसी समस्या के स्केल किया जा सकता है.
नीचे दी गई टेबल में बताया गया है कि बड़े पैमाने पर डेटा को सही तरीके से मैनेज करने के लिए, कब लागू करने का तरीका बदला गया:
| ड्रॉइंग ऑपरेशन को स्केल किया जाना है | एपीआई का पहला लेवल |
| drawText() | 18 |
| drawPosText() | 28 |
| drawTextOnPath() | 28 |
| सामान्य आकार | 17 |
| मुश्किल शेप | 28 |
| drawPath() | 28 |
| शैडो लेयर | 28 |
अगर आपके ऐप्लिकेशन पर, इन सुविधाओं के न होने या सीमाओं का असर पड़ता है, तो setLayerType(View.LAYER_TYPE_SOFTWARE, null) को कॉल करके, अपने ऐप्लिकेशन के सिर्फ़ उस हिस्से के लिए हार्डवेयर ऐक्सेलरेट की सुविधा बंद की जा सकती है जिस पर असर पड़ा है.
इस तरह, आपको अन्य सभी जगहों पर हार्डवेयर से तेज़ी लाने की सुविधा का फ़ायदा मिलता रहेगा.
अपने ऐप्लिकेशन में अलग-अलग लेवल पर हार्डवेयर ऐक्सेलरेट की सुविधा चालू और बंद करने के तरीके के बारे में ज़्यादा जानने के लिए, हार्डवेयर ऐक्सेलरेट की सुविधा कंट्रोल करना लेख पढ़ें.
लेयर देखना
Android के सभी वर्शन में, व्यू को स्क्रीन से बाहर के बफ़र में रेंडर किया जा सकता है. इसके लिए, व्यू की ड्रॉइंग कैश या Canvas.saveLayer का इस्तेमाल किया जा सकता है. स्क्रीन से बाहर मौजूद बफ़र या लेयर का इस्तेमाल कई तरह से किया जा सकता है. इनका इस्तेमाल, मुश्किल व्यू को ऐनिमेट करते समय बेहतर परफ़ॉर्मेंस पाने या कंपोज़िशन इफ़ेक्ट लागू करने के लिए किया जा सकता है. उदाहरण के लिए, Canvas.saveLayer का इस्तेमाल करके फ़ेड इफ़ेक्ट लागू किए जा सकते हैं. इससे किसी व्यू को कुछ समय के लिए लेयर में रेंडर किया जा सकता है. इसके बाद, ओपैसिटी फ़ैक्टर के साथ उसे वापस स्क्रीन पर कंपोज़ किया जा सकता है.
Android 3.0 (एपीआई लेवल 11) से, आपके पास View.setLayerType तरीके का इस्तेमाल करके, यह तय करने का ज़्यादा कंट्रोल होता है कि लेयर का इस्तेमाल कब और कैसे करना है. यह एपीआई दो पैरामीटर लेता है: वह लेयर टाइप जिसका आपको इस्तेमाल करना है और एक वैकल्पिक Paint ऑब्जेक्ट. यह ऑब्जेक्ट बताता है कि लेयर को कैसे कंपोज़ किया जाना चाहिए. किसी लेयर पर कलर फ़िल्टर, खास ब्लेंडिंग मोड या पारदर्शिता लागू करने के लिए, Paint पैरामीटर का इस्तेमाल किया जा सकता है. किसी व्यू में, तीन तरह की लेयर में से किसी एक का इस्तेमाल किया जा सकता है:
LAYER_TYPE_NONE: व्यू को सामान्य तौर पर रेंडर किया जाता है और यह ऑफ-स्क्रीन बफ़र पर आधारित नहीं होता. यह डिफ़ॉल्ट व्यवहार है.LAYER_TYPE_HARDWARE: अगर ऐप्लिकेशन में हार्डवेयर की मदद से रेंडरिंग की सुविधा चालू है, तो व्यू को हार्डवेयर में हार्डवेयर टेक्सचर में रेंडर किया जाता है. अगर ऐप्लिकेशन में हार्डवेयर ऐक्सिलरेशन की सुविधा नहीं है, तो यह लेयर टाइपLAYER_TYPE_SOFTWAREकी तरह काम करता है.LAYER_TYPE_SOFTWARE: इस व्यू को सॉफ़्टवेयर में बिटमैप में रेंडर किया जाता है.
आपके लक्ष्य के हिसाब से, तय किया जाता है कि किस तरह की लेयर का इस्तेमाल किया जाए:
परफ़ॉर्मेंस: व्यू को हार्डवेयर टेक्सचर में रेंडर करने के लिए, हार्डवेयर लेयर टाइप का इस्तेमाल करें. जब किसी व्यू को लेयर में रेंडर किया जाता है, तब उसके ड्रॉइंग कोड को तब तक लागू नहीं किया जाता, जब तक व्यू
invalidateको कॉल नहीं करता. इसके बाद, कुछ ऐनिमेशन, जैसे कि ऐल्फ़ा ऐनिमेशन को सीधे तौर पर लेयर पर लागू किया जा सकता है. यह काम जीपीयू के लिए बहुत आसान होता है.विज़ुअल इफ़ेक्ट: किसी व्यू पर खास विज़ुअल ट्रीटमेंट लागू करने के लिए, हार्डवेयर या सॉफ़्टवेयर लेयर टाइप और
Paintका इस्तेमाल करें. उदाहरण के लिए,ColorMatrixColorFilterका इस्तेमाल करके, किसी व्यू को ब्लैक ऐंड व्हाइट में बनाया जा सकता है.सॉफ़्टवेयर के साथ काम करने की सुविधा: किसी व्यू को सॉफ़्टवेयर में रेंडर करने के लिए, सॉफ़्टवेयर लेयर टाइप का इस्तेमाल करें. अगर हार्डवेयर की मदद से रेंडर किए गए व्यू (उदाहरण के लिए, अगर आपका पूरा ऐप्लिकेशन हार्डवेयर की मदद से रेंडर किया गया है) को रेंडर करने में समस्याएं आ रही हैं, तो हार्डवेयर रेंडरिंग पाइपलाइन की सीमाओं को दूर करने का यह एक आसान तरीका है.
लेयर और ऐनिमेशन देखना
हार्डवेयर लेयर, आपके ऐप्लिकेशन में तेज़ी से और बेहतर ऐनिमेशन दिखा सकती हैं. ऐसा तब होता है, जब आपके ऐप्लिकेशन में हार्डवेयर ऐक्सलरेशन की सुविधा चालू हो. ज़्यादा ड्रॉइंग ऑपरेशन करने वाले कॉम्प्लेक्स व्यू को ऐनिमेट करते समय, हर सेकंड 60 फ़्रेम पर ऐनिमेशन चलाना हमेशा मुमकिन नहीं होता. हार्डवेयर लेयर का इस्तेमाल करके, व्यू को हार्डवेयर टेक्सचर में रेंडर किया जा सकता है. इससे इस समस्या को कम किया जा सकता है. इसके बाद, हार्डवेयर टेक्सचर का इस्तेमाल करके व्यू को ऐनिमेट किया जा सकता है. इससे व्यू को ऐनिमेट करते समय, उसे बार-बार फिर से रेंडर करने की ज़रूरत नहीं पड़ती. जब तक व्यू की प्रॉपर्टी में बदलाव नहीं किया जाता, तब तक व्यू को फिर से नहीं बनाया जाता. प्रॉपर्टी में बदलाव करने पर, invalidate को कॉल किया जाता है. इसके अलावा, invalidate को मैन्युअल तरीके से कॉल करने पर भी व्यू को फिर से बनाया जाता है. अगर आपने अपने ऐप्लिकेशन में कोई ऐनिमेशन चलाया है और आपको मनमुताबिक नतीजे नहीं मिल रहे हैं, तो ऐनिमेटेड व्यू पर हार्डवेयर लेयर चालू करें.
जब व्यू को हार्डवेयर लेयर से बैक किया जाता है, तो उसकी कुछ प्रॉपर्टी को इस तरह से मैनेज किया जाता है कि लेयर को स्क्रीन पर कंपोज़ किया जाता है. इन प्रॉपर्टी को सेट करना ज़्यादा असरदार होगा, क्योंकि इसके लिए व्यू को अमान्य करने और फिर से बनाने की ज़रूरत नहीं होती. यहां उन प्रॉपर्टी की सूची दी गई है जिनसे लेयर के कंपोज़िट होने के तरीके पर असर पड़ता है. इनमें से किसी भी प्रॉपर्टी के लिए सेटर को कॉल करने पर, टारगेट किए गए व्यू को सबसे सही तरीके से अमान्य किया जाता है. साथ ही, उसे फिर से नहीं बनाया जाता:
alpha: इससे लेयर की अपारदर्शिता बदलती हैx,y,translationX,translationY: इससे लेयर की पोज़िशन बदलती हैscaleX,scaleY: इससे लेयर का साइज़ बदलता हैrotation,rotationX,rotationY: इससे 3D स्पेस में लेयर का ओरिएंटेशन बदलता हैpivotX,pivotY: इससे लेयर के ट्रांसफ़ॉर्मेशन का ओरिजन बदल जाता है
इन प्रॉपर्टी के नाम का इस्तेमाल, ObjectAnimator की मदद से व्यू को ऐनिमेट करते समय किया जाता है. अगर आपको इन प्रॉपर्टी को ऐक्सेस करना है, तो सही सेटर या गेटर को कॉल करें. उदाहरण के लिए, ऐल्फ़ा प्रॉपर्टी में बदलाव करने के लिए, setAlpha को कॉल करें. नीचे दिए गए कोड स्निपेट में, Y-ऐक्सिस के चारों ओर 3D में व्यू को रोटेट करने का सबसे सही तरीका दिखाया गया है:
Kotlin
view.setLayerType(View.LAYER_TYPE_HARDWARE, null) ObjectAnimator.ofFloat(view, "rotationY", 180f).start()
Java
view.setLayerType(View.LAYER_TYPE_HARDWARE, null); ObjectAnimator.ofFloat(view, "rotationY", 180).start();
हार्डवेयर लेयर, वीडियो मेमोरी का इस्तेमाल करती हैं. इसलिए, हमारा सुझाव है कि आप इन्हें सिर्फ़ ऐनिमेशन के दौरान चालू करें. ऐनिमेशन पूरा होने के बाद, इन्हें बंद कर दें. ऐनिमेशन लिसनर का इस्तेमाल करके, यह काम किया जा सकता है:
Kotlin
view.setLayerType(View.LAYER_TYPE_HARDWARE, null) ObjectAnimator.ofFloat(view, "rotationY", 180f).apply { addListener(object : AnimatorListenerAdapter() { override fun onAnimationEnd(animation: Animator) { view.setLayerType(View.LAYER_TYPE_NONE, null) } }) start() }
Java
view.setLayerType(View.LAYER_TYPE_HARDWARE, null); ObjectAnimator animator = ObjectAnimator.ofFloat(view, "rotationY", 180); animator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { view.setLayerType(View.LAYER_TYPE_NONE, null); } }); animator.start();
प्रॉपर्टी ऐनिमेशन के बारे में ज़्यादा जानने के लिए, प्रॉपर्टी ऐनिमेशन लेख पढ़ें.
सुझाव और तरकीबें
हार्डवेयर की मदद से रेंडर किए जाने वाले 2D ग्राफ़िक पर स्विच करने से, परफ़ॉर्मेंस तुरंत बेहतर हो सकती है. हालांकि, आपको अपने ऐप्लिकेशन को इस तरह से डिज़ाइन करना चाहिए कि वह GPU का असरदार तरीके से इस्तेमाल कर सके. इसके लिए, इन सुझावों का पालन करें:
- अपने ऐप्लिकेशन में व्यू की संख्या कम करें
- सिस्टम को जितने ज़्यादा व्यू इकट्ठा करने होंगे, उतना ही ज़्यादा समय लगेगा. यह सॉफ़्टवेयर रेंडरिंग पाइपलाइन पर भी लागू होता है. व्यू कम करना, यूज़र इंटरफ़ेस (यूआई) को ऑप्टिमाइज़ करने का सबसे आसान तरीका है.
- ओवरड्रॉ से बचें
- एक-दूसरे के ऊपर बहुत ज़्यादा लेयर न बनाएं. ऐसे सभी व्यू हटाएं जो ऊपर मौजूद अपारदर्शी व्यू की वजह से पूरी तरह से दिख नहीं रहे हैं. अगर आपको एक-दूसरे के ऊपर कई लेयर ब्लेंड करनी हैं, तो उन्हें एक ही लेयर में मर्ज करें. मौजूदा हार्डवेयर के लिए, यह एक अच्छा नियम है कि स्क्रीन पर हर फ़्रेम में पिक्सल की संख्या, स्क्रीन पर मौजूद पिक्सल की संख्या के 2.5 गुना से ज़्यादा न हो. हालांकि, बिटमैप में मौजूद पारदर्शी पिक्सल की गिनती की जाती है!
- ड्रॉ करने के तरीकों में रेंडर ऑब्जेक्ट न बनाएं
- आम तौर पर, रेंडरिंग के हर तरीके को लागू करते समय, नया
Paintया नयाPathबनाया जाता है. इससे गार्बेज कलेक्टर को ज़्यादा बार चलाना पड़ता है. साथ ही, यह हार्डवेयर पाइपलाइन में कैश मेमोरी और ऑप्टिमाइज़ेशन को भी बायपास करता है. - शेप में बार-बार बदलाव न करें
- उदाहरण के लिए, जटिल आकृतियों, पाथ, और सर्कल को टेक्सचर मास्क का इस्तेमाल करके रेंडर किया जाता है. हर बार जब कोई पाथ बनाया या उसमें बदलाव किया जाता है, तो हार्डवेयर पाइपलाइन एक नया मास्क बनाती है. इसमें ज़्यादा समय लग सकता है.
- बिटमैप में बार-बार बदलाव न करें
- जब भी किसी बिट मैप के कॉन्टेंट में बदलाव किया जाता है, तो उसे अगली बार ड्रॉ करने पर, जीपीयू टेक्सचर के तौर पर फिर से अपलोड किया जाता है.
- ऐल्फ़ा वर्शन का इस्तेमाल सावधानी से करें
setAlpha,AlphaAnimationयाObjectAnimatorका इस्तेमाल करके किसी व्यू को पारदर्शी बनाने पर, उसे स्क्रीन से बाहर मौजूद बफ़र में रेंडर किया जाता है. इससे फ़िल रेट की ज़रूरत दोगुनी हो जाती है. बहुत बड़े व्यू पर ऐल्फ़ा लागू करते समय, व्यू के लेयर टाइप कोLAYER_TYPE_HARDWAREपर सेट करें.