invalidate() Android में View क्लास का एक मेथड है जो व्यू को पुनः चित्रित करने की आवश्यकता वाला चिह्नित करता है। invalidate() को कॉल करने से अगले स्क्रीन रिफ्रेश चक्र में व्यू का पुनः चित्रण होता है, जो इसे कस्टम कम्पोनेंट की विज़ुअल स्थिति को अपडेट करने का प्राथमिक तंत्र बनाता है। Android Developers Documentation (2025) के अनुसार, invalidate() का उपयोग 90% कस्टम View में डेटा परिवर्तनों को स्क्रीन पर प्रदर्शन के साथ सिंक्रोनाइज़ करने के लिए किया जाता है। मेथड एसिंक्रोनस रूप से काम करता है — यह केवल dirty फ़्लैग सेट करता है और तुरंत नियंत्रण लौटाता है।
मुख्य बातें
invalidate() android.view.View क्लास का एक मेथड है जो Android सिस्टम को बताता है कि व्यू का विज़ुअल प्रतिनिधित्व पुराना हो गया है। मेथड को कॉल करने के बाद, सिस्टम व्यू को dirty के रूप में चिह्नित करता है और अगले स्क्रीन रिफ्रेश चक्र (आमतौर पर 60 FPS के लिए 16 ms) में इसके पुनः चित्रण को निर्धारित करता है।
invalidate() मेथड विभिन्न रूपों में आता है: बिना पैरामीटर (पूर्ण पुनः चित्रण), Rect पैरामीटर के साथ (आंशिक), और ltrb पैरामीटर (left, top, right, bottom) के साथ। सभी संस्करण एसिंक्रोनस रूप से काम करते हैं और UI थ्रेड से कॉल किए जाने चाहिए। बैकग्राउंड थ्रेड से कॉल करने के लिए postInvalidate() मौजूद है।
Android में पुनः चित्रण तंत्र ViewRootImpl पर आधारित है — एक आंतरिक घटक जो View Hierarchy को चित्रण के लिए Surface से जोड़ता है। जब invalidate() कॉल किया जाता है, ViewRootImpl व्यू क्षेत्र को dirty के रूप में चिह्नित करता है और Choreographer के माध्यम से पुनः चित्रण अनुरोध भेजता है — एक सिस्टम सेवा जो चित्रण को स्क्रीन रिफ्रेश दर के साथ सिंक्रोनाइज़ करती है।
Choreographer Vsync से सिग्नल प्राप्त करता है और तीन-चरणीय प्रक्रिया शुरू करता है: measure, layout, draw। हालांकि, invalidate() केवल draw चरण को प्रभावित करता है — measure और layout चरण तब तक निष्पादित नहीं होते जब तक requestLayout() कॉल न किया गया हो। यह एक मुख्य अंतर है: invalidate() requestLayout() से सस्ता है क्योंकि यह ज्यामिति की पुनर्गणना नहीं करता।
class CustomChartView(context: Context, attrs: AttributeSet?)
: View(context, attrs) {
private var dataPoints: List<Float> = emptyList()
private val paint = Paint(Paint.ANTI_ALIAS_FLAG)
fun updateData(newPoints: List<Float>) {
dataPoints = newPoints
invalidate() // पुनः चित्रण अनुरोध
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
paint.color = Color.BLUE
paint.strokeWidth = 4f
paint.style = Paint.Style.STROKE
// चार्ट लाइन खींचना
val path = Path()
dataPoints.forEachIndexed { index, value ->
val x = index * width / max(dataPoints.size - 1, 1)
val y = height - value * height
if (index == 0) path.moveTo(x, y)
else path.lineTo(x, y)
}
canvas.drawPath(path, paint)
}
}
इस उदाहरण में, ग्राफ चित्रित करने वाला एक कस्टम View डेटा अपडेट होने पर invalidate() कॉल करता है। सिस्टम पदानुक्रम में अन्य तत्वों को प्रभावित किए बिना केवल इस View को पुनः चित्रित करता है। onDraw() Path के माध्यम से रेखाएँ चित्रित करने के लिए Canvas प्राप्त करता है।
invalidate() और postInvalidate() के बीच मुख्य अंतर थ्रेड सुरक्षा में है। invalidate() को केवल UI थ्रेड (मुख्य थ्रेड) से कॉल किया जाना चाहिए। postInvalidate() को किसी भी थ्रेड से कॉल किया जा सकता है — यह Handler के माध्यम से UI थ्रेड को पुनः चित्रण अनुरोध भेजता है।
| विशेषता | invalidate() | postInvalidate() |
|---|---|---|
| कॉल थ्रेड | UI थ्रेड (मुख्य थ्रेड) | कोई भी थ्रेड |
| तंत्र | सीधे dirty फ़्लैग अपडेट | Handler.post() के माध्यम से UI थ्रेड तक |
| विलंबता | न्यूनतम, वर्तमान चक्र में | अगले UI थ्रेड चक्र तक |
| प्रदर्शन | उच्च | Handler पर थोड़ा ओवरहेड |
| अनुशंसा | UI थ्रेड के लिए हमेशा invalidate() | केवल बैकग्राउंड थ्रेड के लिए |
व्यवहार में, postInvalidate() का उपयोग नेटवर्क डेटा लोडिंग, सेंसर परिणाम प्रसंस्करण या बैकग्राउंड गणनाओं के परिदृश्यों में किया जाता है। यदि आप UI थ्रेड में हैं — न्यूनतम विलंबता के लिए हमेशा invalidate() का उपयोग करें।
// UI थ्रेड से कॉल किया गया
view.invalidate()
// बैकग्राउंड थ्रेड से कॉल किया गया
Thread {
// भारी गणनाएँ
val result = performHeavyCalculation()
runOnUiThread {
updateUi(result)
}
}.start()
invalidate(Rect) और invalidate(int l, int t, int r, int b) पुनः चित्रण क्षेत्र को सीमित करने की अनुमति देते हैं। यह प्रदर्शन के लिए महत्वपूर्ण है: जब View का केवल एक भाग बदलता है (जैसे, कर्सर संचलन, संकेतक परिवर्तन), तो पूरे व्यू को पुनः चित्रित करने की कोई आवश्यकता नहीं है।
सिस्टम निर्दिष्ट dirty आयत को onDraw() में canvas.clipBounds के माध्यम से भेजता है। onDraw() के अंदर, आप clipBounds की जाँच कर सकते हैं और केवल उस क्षेत्र के भीतर चित्रित कर सकते हैं, हालाँकि Android Canvas स्वचालित रूप से dirty आयत के बाहर चित्रण को क्लिप करता है।
// आंशिक अपडेट: केवल कर्सर क्षेत्र
private val cursorRect = Rect()
fun moveCursorTo(newX: Int, newY: Int) {
// पुरानी स्थिति को अमान्य करें
invalidate(cursorRect)
cursorRect.set(newX - 5, newY - 5,
newX + 5, newY + 5)
// नई स्थिति को अमान्य करें
invalidate(cursorRect)
}
आंशिक पुनः चित्रण के बिना, प्रत्येक कर्सर संचलन पूरे View को पुनः चित्रित करेगा, जो एक बड़े ग्राफ के लिए कुछ दर्जन के बजाय हज़ारों पिक्सेल को पुनः चित्रित करने के बराबर है। invalidate(Rect) संपादकों, चित्रण कैनवस और एनिमेटेड घटकों के लिए एक अनिवार्य तकनीक है।
एक सामान्य गलती है requestLayout() को कॉल करना जहाँ invalidate() पर्याप्त होगा, और इसके विपरीत। अंतर मौलिक है: invalidate() केवल draw चरण को प्रभावित करता है, जबकि requestLayout() एक पूर्ण measure → layout → draw चक्र शुरू करता है।
| पहलू | invalidate() | requestLayout() |
|---|---|---|
| चक्र चरण | केवल draw | measure + layout + draw |
| कब उपयोग करें | केवल रेंडरिंग बदलती है (रंग, पाठ, ग्राफिक्स) | View का आकार या स्थिति बदलती है |
| प्रदर्शन | हल्का — केवल पुनः चित्रण | भारी — पदानुक्रम की पुनर्गणना |
| पदानुक्रम पर प्रभाव | केवल वर्तमान View | मूल कंटेनरों को प्रभावित कर सकता है |
यदि आप TextView में पाठ बदलते हैं, तो invalidate() पर्याप्त है क्योंकि View का आकार नहीं बदलता। यदि पाठ एक नई पंक्ति में जा सकता है और ऊँचाई बढ़ा सकता है, तो requestLayout() की आवश्यकता है। Android Lint प्रदर्शन नियमों के माध्यम से ऐसी त्रुटियों को ट्रैक करने में मदद करता है।
अत्यधिक invalidate() कॉल Android में कस्टम View के खराब प्रदर्शन के मुख्य कारणों में से एक हैं। आइए अनुकूलन तकनीकों पर नज़र डालें।
यदि डेटा उच्च आवृत्ति (सेंसर, एनिमेशन, वीडियो) पर अपडेट होता है, तो प्रत्येक परिवर्तन पर invalidate() कॉल न करें। स्क्रीन रिफ्रेश दर के साथ सिंक्रोनाइज़ करने के लिए ValueAnimator या Choreographer.FrameCallback का उपयोग करें। यह सुनिश्चित करता है कि invalidate() प्रति फ्रेम एक बार से अधिक कॉल न हो।
API 14 से, Android GPU के माध्यम से हार्डवेयर त्वरण का समर्थन करता है। यदि आपका कस्टम View केवल Canvas API (drawRect, drawCircle, drawPath) का उपयोग करता है, तो त्वरण पारदर्शी रूप से काम करता है। DisplayList-संगत संचालन के लिए, invalidate() काफी तेज़ी से संसाधित होता है।
// Vsync सिंक के लिए Choreographer का उपयोग करना
private val frameCallback = Choreographer.FrameCallback { frameTimeNanos ->
updateAnimation(frameTimeNanos)
invalidate()
Choreographer.getInstance().postFrameCallback(this)
}
fun startAnimation() {
Choreographer.getInstance().postFrameCallback(frameCallback)
}
लक्षित अपडेट के लिए invalidate(Rect) का उपयोग करें, onDraw() से invalidate() कॉल करने से बचें (अनंत लूप), और हमेशा डिवाइस पर GPU Profile Rendering के माध्यम से प्रोफाइल करें। यह प्रत्येक फ्रेम का सटीक रेंडरिंग समय दिखाएगा और समस्या क्षेत्रों की पहचान करने में मदद करेगा।
अक्सर पूछे जाने वाले प्रश्न
नहीं, onDraw() के अंदर invalidate() कॉल करने से एक अनंत पुनः चित्रण लूप बनता है: onDraw() invalidate() कॉल करता है, जो फिर से onDraw() को ट्रिगर करता है। इससे CPU 100% उपयोग और फ्रेम ड्रॉप होता है। ValueAnimator या Choreographer के माध्यम से एनिमेशन का उपयोग करें।
invalidate() केवल UI थ्रेड में काम करता है और dirty फ़्लैग को तुरंत अपडेट करता है। postInvalidate() Handler के माध्यम से UI थ्रेड को अनुरोध भेजता है और किसी भी बैकग्राउंड थ्रेड से कॉल किया जा सकता है। यदि आप UI थ्रेड में हैं — न्यूनतम विलंबता के लिए invalidate() का उपयोग करें।
हाँ, आंतरिक रूप से TextView का setText() मेथड पाठ अपडेट करने के बाद invalidate() कॉल करता है। यदि पाठ View के आयाम बदलता है, तो requestLayout() भी कॉल किया जाता है। मानक विजेट्स के साथ काम करते समय डेवलपर्स को मैन्युअल रूप से invalidate() कॉल करने की आवश्यकता नहीं है।
प्रत्येक invalidate() कॉल अगले Vsync (हर 16 ms) में पुनः चित्रण निर्धारित करता है। यदि onDraw() को 16 ms से अधिक समय लगता है, तो फ्रेम ड्रॉप होता है। onDraw() को अनुकूलित करें — Bitmap को कैश करें, आवंटन से बचें, और GPU रेंडरिंग के लिए हार्डवेयर त्वरण का उपयोग करें।
हाँ, Paint गुण (रंग, मोटाई, शैली) बदलने के बाद, आपको invalidate() कॉल करना होगा, क्योंकि View स्वचालित रूप से Paint ऑब्जेक्ट में परिवर्तनों को ट्रैक नहीं करता। सिस्टम नहीं जानता कि Paint बदल गया है और स्पष्ट अनुरोध के बिना onDraw() कॉल नहीं करेगा।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें