invalidate() — এটি কী, পুনরায় আঁকার মেকানিজম এবং invalidate(Rect)

লেখক: IT Sectr প্রকাশিত: 2026-07-20 পড়ার সময়: 7 মিনিট

invalidate() হল Android-এ View ক্লাসের একটি মেথড যা একটি ভিউকে পুনরায় আঁকার প্রয়োজন হিসাবে চিহ্নিত করে। invalidate() কল করলে পরবর্তী স্ক্রিন রিফ্রেশ চক্রে ভিউটির পুনরায় আঁকা ঘটে, যা এটিকে কাস্টম কম্পোনেন্টের ভিজুয়াল অবস্থা আপডেট করার প্রাথমিক প্রক্রিয়া করে তোলে। Android Developers Documentation (2025) অনুসারে, 90% কাস্টম View-এ ডেটা পরিবর্তনগুলিকে স্ক্রিনে প্রদর্শনের সাথে সিঙ্ক্রোনাইজ করতে invalidate() ব্যবহার করা হয়। মেথডটি অ্যাসিঙ্ক্রোনাসভাবে কাজ করে — এটি কেবল dirty ফ্ল্যাগ সেট করে এবং সঙ্গে সঙ্গে নিয়ন্ত্রণ ফিরিয়ে দেয়।

মূল বিষয়

  • invalidate() — Android-এ View পুনরায় আঁকার একটি অ্যাসিঙ্ক্রোনাস অনুরোধ, dirty ফ্ল্যাগ প্রক্রিয়ার মাধ্যমে কাজ করে
  • postInvalidate() — ব্যাকগ্রাউন্ড থ্রেড থেকে কল করার জন্য invalidate()-এর সংস্করণ, থ্রেড-সেফ
  • invalidate(Rect) — কর্মক্ষমতা অপ্টিমাইজেশনের জন্য শুধুমাত্র নির্দিষ্ট এলাকার আংশিক পুনরায় আঁকা
  • onDraw() — মেথড যা invalidate()-এর পরে সিস্টেম দ্বারা কল করা হয়, iOS-এ draw(_:) এর অনুরূপ
  • invalidate() vs requestLayout() — invalidate() বিষয়বস্তু পুনরায় আঁকে, requestLayout() জ্যামিতি পুনরায় গণনা করে

Android-এ invalidate() কী

invalidate() হল android.view.View ক্লাসের একটি মেথড যা Android সিস্টেমকে জানায় যে একটি ভিউয়ের ভিজুয়াল উপস্থাপনা পুরানো হয়ে গেছে। মেথডটি কল করার পর, সিস্টেম ভিউটিকে dirty হিসাবে চিহ্নিত করে এবং পরবর্তী স্ক্রিন রিফ্রেশ চক্রে (সাধারণত 60 FPS-এর জন্য 16 ms) এর পুনরায় আঁকার সময় নির্ধারণ করে।

invalidate() মেথডটি বিভিন্ন রূপে আসে: প্যারামিটার ছাড়া (সম্পূর্ণ পুনরায় আঁকা), Rect প্যারামিটার সহ (আংশিক), এবং ltrb প্যারামিটার (left, top, right, bottom) সহ। সব সংস্করণ অ্যাসিঙ্ক্রোনাসভাবে কাজ করে এবং UI থ্রেড থেকে কল করা উচিত। ব্যাকগ্রাউন্ড থ্রেড থেকে কল করার জন্য postInvalidate() রয়েছে।

invalidate()-এর মাধ্যমে পুনরায় আঁকা কিভাবে কাজ করে

Android-এ পুনরায় আঁকার প্রক্রিয়া ViewRootImpl-এর উপর ভিত্তি করে — একটি অভ্যন্তরীণ কম্পোনেন্ট যা View Hierarchy-কে আঁকার জন্য Surface-এর সাথে সংযুক্ত করে। যখন invalidate() কল করা হয়, ViewRootImpl ভিউ এলাকাটিকে dirty হিসাবে চিহ্নিত করে এবং Choreographer-এর মাধ্যমে পুনরায় আঁকার অনুরোধ পাঠায় — একটি সিস্টেম সার্ভিস যা স্ক্রিন রিফ্রেশ হারের সাথে আঁকাকে সিঙ্ক্রোনাইজ করে।

পুনরায় আঁকার চক্র

Choreographer Vsync থেকে সিগন্যাল পায় এবং একটি ত্রি-পদক্ষেপ প্রক্রিয়া শুরু করে: measure, layout, draw। তবে, invalidate() শুধুমাত্র draw ধাপকে প্রভাবিত করে — measure এবং layout ধাপগুলি কার্যকর করা হয় না যতক্ষণ না requestLayout() কল করা হয়। এটি একটি মূল পার্থক্য: invalidate() requestLayout()-এর চেয়ে সস্তা কারণ এটি জ্যামিতি পুনরায় গণনা করে না।

kotlin
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() এবং postInvalidate()-এর মধ্যে প্রধান পার্থক্য থ্রেড নিরাপত্তায়। invalidate() শুধুমাত্র UI থ্রেড (মূল থ্রেড) থেকে কল করা উচিত। postInvalidate() যেকোনো থ্রেড থেকে কল করা যেতে পারে — এটি Handler-এর মাধ্যমে UI থ্রেডে পুনরায় আঁকার অনুরোধ পাঠায়।

বৈশিষ্ট্যinvalidate()postInvalidate()
কল থ্রেডUI থ্রেড (মূল থ্রেড)যেকোনো থ্রেড
প্রক্রিয়াসরাসরি dirty ফ্ল্যাগ আপডেটHandler.post()-এর মাধ্যমে UI থ্রেডে
বিলম্বসর্বনিম্ন, বর্তমান চক্রেপরবর্তী UI থ্রেড চক্র পর্যন্ত
কর্মক্ষমতাউচ্চHandler-এ সামান্য ওভারহেড
সুপারিশUI থ্রেডের জন্য সর্বদা invalidate()শুধুমাত্র ব্যাকগ্রাউন্ড থ্রেডের জন্য

অনুশীলনে, postInvalidate() নেটওয়ার্ক ডেটা লোডিং, সেন্সর ফলাফল প্রক্রিয়াকরণ বা ব্যাকগ্রাউন্ড গণনার দৃশ্যে ব্যবহৃত হয়। আপনি যদি UI থ্রেডে থাকেন — সর্বনিম্ন বিলম্বের জন্য সর্বদা invalidate() ব্যবহার করুন।

kotlin
    // UI থ্রেড থেকে কল করা হয়েছে
view.invalidate()

    // ব্যাকগ্রাউন্ড থ্রেড থেকে কল করা হয়েছে
Thread {
    // ভারী গণনা
    val result = performHeavyCalculation()
    runOnUiThread {
        updateUi(result)
    }
}.start()

invalidate(Rect)-এর মাধ্যমে আংশিক পুনরায় আঁকা

invalidate(Rect) এবং invalidate(int l, int t, int r, int b) পুনরায় আঁকার এলাকা সীমিত করার অনুমতি দেয়। এটি কর্মক্ষমতার জন্য অত্যন্ত গুরুত্বপূর্ণ: যখন একটি View-এর শুধুমাত্র একটি অংশ পরিবর্তিত হয় (যেমন, কার্সার চলাচল, নির্দেশক পরিবর্তন), তখন পুরো ভিউটি পুনরায় আঁকার প্রয়োজন নেই।

সিস্টেম নির্দিষ্ট dirty আয়তক্ষেত্রটি onDraw()-এ canvas.clipBounds-এর মাধ্যমে পাঠায়। onDraw()-এর ভিতরে, আপনি clipBounds পরীক্ষা করতে পারেন এবং শুধুমাত্র সেই এলাকার মধ্যে আঁকতে পারেন, যদিও Android Canvas স্বয়ংক্রিয়ভাবে dirty আয়তক্ষেত্রের বাইরে আঁকা ক্লিপ করে।

kotlin
    // আংশিক আপডেট: শুধুমাত্র কার্সার এলাকা
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) এডিটর, আঁকা ক্যানভাস এবং অ্যানিমেটেড কম্পোনেন্টের জন্য একটি অপরিহার্য কৌশল।

invalidate() বনাম requestLayout(): পার্থক্য কী

একটি সাধারণ ভুল হল requestLayout() কল করা যেখানে invalidate() যথেষ্ট হবে, এবং এর বিপরীত। পার্থক্যটি মৌলিক: invalidate() শুধুমাত্র draw ধাপকে প্রভাবিত করে, যেখানে requestLayout() একটি সম্পূর্ণ measure → layout → draw চক্র শুরু করে।

দিকinvalidate()requestLayout()
চক্রের ধাপশুধুমাত্র drawmeasure + layout + draw
কখন ব্যবহার করবেনশুধুমাত্র রেন্ডারিং পরিবর্তিত হয় (রঙ, পাঠ্য, গ্রাফিক্স)View-এর আকার বা অবস্থান পরিবর্তিত হয়
কর্মক্ষমতাহালকা — শুধুমাত্র পুনরায় আঁকাভারী — শ্রেণিবিন্যাস পুনরায় গণনা
শ্রেণিবিন্যাসের উপর প্রভাবশুধুমাত্র বর্তমান Viewপিতৃ পাত্রগুলিকে প্রভাবিত করতে পারে

আপনি যদি TextView-এ পাঠ্য পরিবর্তন করেন, তাহলে invalidate() যথেষ্ট কারণ View-এর আকার পরিবর্তন হয় না। যদি পাঠ্য একটি নতুন লাইনে যেতে পারে এবং উচ্চতা বাড়াতে পারে, তাহলে requestLayout() প্রয়োজন। Android Lint কর্মক্ষমতা নিয়মের মাধ্যমে এই ধরনের ত্রুটিগুলি ট্র্যাক করতে সহায়তা করে।

invalidate() কর্মক্ষমতা অপ্টিমাইজেশন

অতিরিক্ত invalidate() কলগুলি Android-এ কাস্টম View-এর খারাপ কর্মক্ষমতার প্রধান কারণগুলির মধ্যে একটি। আসুন অপ্টিমাইজেশন কৌশলগুলি দেখি।

কলের ফ্রিকোয়েন্সি কমিয়ে দিন

যদি ডেটা উচ্চ ফ্রিকোয়েন্সিতে (সেন্সর, অ্যানিমেশন, ভিডিও) আপডেট হয়, তাহলে প্রতিটি পরিবর্তনে invalidate() কল করবেন না। স্ক্রিন রিফ্রেশ হারের সাথে সিঙ্ক্রোনাইজ করতে ValueAnimator বা Choreographer.FrameCallback ব্যবহার করুন। এটি নিশ্চিত করে যে invalidate() প্রতি ফ্রেমে একবারের বেশি কল না হয়।

হার্ডওয়্যার এক্সিলারেশন ব্যবহার করুন

API 14 থেকে, Android GPU-এর মাধ্যমে হার্ডওয়্যার এক্সিলারেশন সমর্থন করে। যদি আপনার কাস্টম View শুধুমাত্র Canvas API (drawRect, drawCircle, drawPath) ব্যবহার করে, তাহলে এক্সিলারেশন স্বচ্ছভাবে কাজ করে। DisplayList-সামঞ্জস্যপূর্ণ অপারেশনের জন্য, invalidate() উল্লেখযোগ্যভাবে দ্রুত প্রক্রিয়া করা হয়।

kotlin
// 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() invalidate() কল করে, যা আবার onDraw() ট্রিগার করে। এটি CPU-র 100% ব্যবহার এবং ফ্রেম ড্রপের কারণ হয়। ValueAnimator বা Choreographer-এর মাধ্যমে অ্যানিমেশন ব্যবহার করুন।

কিভাবে invalidate() postInvalidate() থেকে আলাদা?

invalidate() শুধুমাত্র UI থ্রেডে কাজ করে এবং সঙ্গে সঙ্গে dirty ফ্ল্যাগ আপডেট করে। postInvalidate() Handler-এর মাধ্যমে UI থ্রেডে একটি অনুরোধ পাঠায় এবং যেকোনো ব্যাকগ্রাউন্ড থ্রেড থেকে কল করা যেতে পারে। আপনি যদি UI থ্রেডে থাকেন — সর্বনিম্ন বিলম্বের জন্য invalidate() ব্যবহার করুন।

TextView-এ setText() কি স্বয়ংক্রিয়ভাবে invalidate() কল করে?

হ্যাঁ, অভ্যন্তরীণভাবে TextView-এর setText() মেথড পাঠ্য আপডেট করার পর invalidate() কল করে। যদি পাঠ্য View-এর মাত্রা পরিবর্তন করে, তাহলে অতিরিক্তভাবে requestLayout() কল করা হয়। স্ট্যান্ডার্ড উইজেটগুলির সাথে কাজ করার সময় ডেভেলপারদের ম্যানুয়ালি invalidate() কল করার প্রয়োজন নেই।

60 FPS-এ invalidate() কীভাবে কর্মক্ষমতা প্রভাবিত করে?

প্রতিটি invalidate() কল পরবর্তী Vsync-এ (প্রতি 16 ms) পুনরায় আঁকার সময় নির্ধারণ করে। যদি onDraw() 16 ms-এর বেশি সময় নেয়, তাহলে ফ্রেম ড্রপ হয়। onDraw() অপ্টিমাইজ করুন — Bitmap ক্যাশ করুন, বরাদ্দ এড়িয়ে চলুন, এবং GPU রেন্ডারিংয়ের জন্য হার্ডওয়্যার এক্সিলারেশন ব্যবহার করুন।

Paint বৈশিষ্ট্য পরিবর্তনের পরে কি invalidate() কল করা প্রয়োজন?

হ্যাঁ, Paint বৈশিষ্ট্য (রঙ, পুরুত্ব, শৈলী) পরিবর্তনের পরে, আপনাকে invalidate() কল করতে হবে, কারণ View স্বয়ংক্রিয়ভাবে Paint অবজেক্টের পরিবর্তনগুলি ট্র্যাক করে না। সিস্টেম জানে না যে Paint পরিবর্তিত হয়েছে এবং স্পষ্ট অনুরোধ ছাড়া onDraw() কল করবে না।

সারসংক্ষেপ

  • invalidate() — Android-এ View পুনরায় আঁকার অনুরোধের প্রাথমিক প্রক্রিয়া, dirty ফ্ল্যাগের মাধ্যমে অ্যাসিঙ্ক্রোনাসভাবে কাজ করে
  • postInvalidate() — ব্যাকগ্রাউন্ড থ্রেড থেকে কলের জন্য থ্রেড-সেফ সংস্করণ, Handler ব্যবহার করে
  • invalidate(Rect) — শুধুমাত্র নির্দিষ্ট এলাকার আংশিক পুনরায় আঁকা, লক্ষ্যযুক্ত পরিবর্তনের জন্য কর্মক্ষমতার জন্য গুরুত্বপূর্ণ
  • requestLayout() — সম্পূর্ণ measure + layout + draw চক্র শুরু করে, invalidate()-এর চেয়ে উল্লেখযোগ্যভাবে ভারী
  • Choreographer — Vsync সিঙ্ক্রোনাইজেশনের জন্য সিস্টেম সার্ভিস, invalidate()-এর সাথে অ্যানিমেশনের জন্য সুপারিশকৃত
  • Hardware Acceleration — API 14 থেকে উপলব্ধ GPU ত্বরণ, Canvas API-র জন্য invalidate() প্রক্রিয়াকরণ দ্রুত করে
  • GPU Profile Rendering — রেন্ডারিং সময় পরিমাপ এবং ধীর onDraw() মেথড সনাক্ত করার জন্য প্রোফাইলিং টুল

আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব

IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।

প্রকল্প নিয়ে আলোচনা করুন

আরও পড়ুন