invalidate() — wat is het, hertekeningsmechanisme en invalidate(Rect)

Auteur: IT Sectr Gepubliceerd: 2026-07-20 Leestijd: 7 min

invalidate() — is een methode van de klasse View in Android die een weergave markeert als opnieuw getekend moet worden. Het aanroepen van invalidate() leidt tot het hertekenen van de weergave in de dichtstbijzijnde verversingscyclus van het scherm, waardoor het het belangrijkste mechanisme is voor het bijwerken van de visuele status van aangepaste componenten. Volgens Android Developers Documentation (2025) wordt invalidate() gebruikt in 90% van de aangepaste Views om gegevenswijzigingen te synchroniseren met de weergave op het scherm. De methode werkt asynchroon — het stelt alleen de dirty-vlag in en geeft onmiddellijk de controle terug.

Belangrijkste

  • invalidate() — asynchroon verzoek tot hertekening van View in Android, werkt via dirty-vlagmechanisme
  • postInvalidate() — versie van invalidate() voor aanroep vanuit achtergrondthread, threadveilig
  • invalidate(Rect) — gedeeltelijke hertekening alleen van het opgegeven gebied voor prestatieoptimalisatie
  • onDraw() — methode die door het systeem wordt aangeroepen na invalidate(), analoog aan draw(_:) in iOS
  • invalidate() vs requestLayout() — invalidate() hertekent inhoud, requestLayout() herberekent geometrie

Wat is invalidate() in Android

invalidate() — is een methode van de klasse android.view.View die het Android-systeem informeert dat de visuele weergave van de view verouderd is. Na het aanroepen van de methode markeert het systeem de view als dirty en plant het hertekenen ervan in de dichtstbijzijnde schermverversingscyclus (meestal 16 ms voor 60 FPS).

De methode invalidate() neemt verschillende vormen aan: zonder parameters (volledige hertekening), met de parameter Rect (gedeeltelijk) en met de parameters ltrb (left, top, right, bottom). Alle versies werken asynchroon en kunnen vanuit de UI-thread worden aangeroepen. Voor aanroep vanuit achtergrondthreads bestaat postInvalidate().

Hoe werkt hertekening via invalidate()

Het hertekeningsmechanisme in Android is gebaseerd op ViewRootImpl — een interne component die View Hierarchy verbindt met Surface voor het tekenen. Wanneer invalidate() wordt aangeroepen, markeert ViewRootImpl het gebied van de view als dirty en stuurt een verzoek tot hertekening via Choreographer — een systeemservice die het tekenen synchroniseert met de schermverversingsfrequentie.

Hertekeningscyclus

Choreographer ontvangt het signaal van Vsync en start een drievoudige doorgang: measure, layout, draw. Echter, invalidate() heeft alleen invloed op de draw-fase — de measure- en layout-fasen worden niet uitgevoerd tenzij requestLayout() is aangeroepen. Dit is het belangrijkste verschil: invalidate() is goedkoper dan requestLayout() omdat het de geometrie niet herberekent.

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() // Hertekeningsverzoek
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        paint.color = Color.BLUE
        paint.strokeWidth = 4f
        paint.style = Paint.Style.STROKE

        // Grafieklijn tekenen
        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)
    }
}

In dit voorbeeld roept een aangepaste View voor het tekenen van een grafiek invalidate() aan bij het bijwerken van gegevens. Het systeem hertekent alleen deze View, zonder de overige elementen van de hiërarchie te beïnvloeden. onDraw() ontvangt Canvas voor het tekenen van lijnen via Path.

invalidate() vs postInvalidate()

Het belangrijkste verschil tussen invalidate() en postInvalidate() is de threadveiligheid. invalidate() mag alleen vanuit de UI-thread (hoofdthread) worden aangeroepen. postInvalidate() kan vanuit elke thread worden aangeroepen — via Handler stuurt het een hertekeningsverzoek naar de UI-thread.

Kenmerkinvalidate()postInvalidate()
AanroepthreadUI-thread (hoofdthread)Elke thread
MechanismeDirecte update van dirty-vlagVia Handler.post() naar UI-thread
LatentieMinimaal, in huidige cyclusTot volgende cyclus van UI-thread
PrestatieHoogKleine overhead op Handler
AanbevelingVoor UI-thread altijd invalidate()Alleen voor achtergrondthreads

In de praktijk wordt postInvalidate() gebruikt in scenario's van het laden van gegevens uit netwerk, verwerking van sensorresultaten of achtergrondberekeningen. Als u zich in de UI-thread bevindt — gebruik dan altijd invalidate() voor minimale latentie.

kotlin
    // Aangeroepen vanuit UI-thread
view.invalidate()

    // Aangeroepen vanuit achtergrondthread
Thread {
    // Zware berekeningen
    val result = performHeavyCalculation()
    runOnUiThread {
        updateUi(result)
    }
}.start()

Gedeeltelijke hertekening via invalidate(Rect)

invalidate(Rect) en invalidate(int l, int t, int r, int b) maken het mogelijk het hertekeningsgebied te beperken. Dit is cruciaal voor prestaties: bij het bijwerken van slechts een deel van View (bijvoorbeeld cursorverplaatsing, indicatorwijziging) heeft het geen zin om de hele view te hertekenen.

Het systeem geeft de opgegeven dirty-rechthoek door aan onDraw() via canvas.clipBounds. Binnen onDraw() kan clipBounds worden gecontroleerd en alleen binnen dit gebied worden getekend, hoewel Android Canvas automatisch het tekenen buiten de dirty-rechthoek begrenst.

kotlin
    // Gedeeltelijke update: alleen cursorgebied
private val cursorRect = Rect()

fun moveCursorTo(newX: Int, newY: Int) {
    // Oude positie ongeldig maken
    invalidate(cursorRect)

    cursorRect.set(newX - 5, newY - 5,
                  newX + 5, newY + 5)

    // Nieuwe positie ongeldig maken
    invalidate(cursorRect)
}

Zonder gedeeltelijke hertekening zou elke cursorverplaatsing de hele View hertekenen, wat voor een grote grafiek betekent dat duizenden pixels worden hertekend in plaats van enkele tientallen. invalidate(Rect) — een verplichte techniek voor editors, teken canvassen en geanimeerde componenten.

invalidate() vs requestLayout(): wat is het verschil

Een veelgemaakte fout is het aanroepen van requestLayout() waar invalidate() voldoende is, en omgekeerd. Het verschil is fundamenteel: invalidate() heeft alleen invloed op de draw-fase, terwijl requestLayout() de volledige measure → layout → draw-cyclus start.

Aspectinvalidate()requestLayout()
CyclusfasenAlleen drawmeasure + layout + draw
Wanneer gebruikenAlleen tekening verandert (kleur, tekst, grafiek)Grootte of positie van view verandert
PrestatieLicht — alleen hertekeningZwaar — herberekening hiërarchie
Invloed op hiërarchieAlleen huidige viewKan bovenliggende containers beïnvloeden

Als u tekst in TextView wijzigt — is invalidate() voldoende, omdat de grootte van de view niet verandert. Als de tekst naar een nieuwe regel kan gaan en de hoogte kan vergroten — is requestLayout() nodig. Android Lint helpt dergelijke fouten te volgen via prestatieregels.

Prestatieoptimalisatie van invalidate()

Overmatige invalidate()-aanroepen — een van de belangrijkste oorzaken van lage prestaties van aangepaste Views in Android. Laten we optimalisatietechnieken bekijken.

Minimaliseer de aanroepfrequentie

Als gegevens met hoge frequentie worden bijgewerkt (sensoren, animatie, video), roep dan niet invalidate() aan bij elke wijziging. Gebruik ValueAnimator of Choreographer.FrameCallback voor synchronisatie met de schermverversingsfrequentie. Dit garandeert dat invalidate() niet vaker dan één keer per frame wordt aangeroepen.

Gebruik Hardware Acceleration

Vanaf API 14 ondersteunt Android hardwareversnelling via GPU. Als uw aangepaste View alleen Canvas API (drawRect, drawCircle, drawPath) gebruikt, werkt de versnelling transparant. Voor DisplayList-compatibele bewerkingen wordt invalidate() aanzienlijk sneller verwerkt.

kotlin
// Choreographer gebruiken voor Vsync-synchronisatie
private val frameCallback = Choreographer.FrameCallback { frameTimeNanos ->
    updateAnimation(frameTimeNanos)
    invalidate()
    Choreographer.getInstance().postFrameCallback(this)
}

fun startAnimation() {
    Choreographer.getInstance().postFrameCallback(frameCallback)
}

Gebruik invalidate(Rect) voor puntige updates, vermijd het aanroepen van invalidate() vanuit onDraw() (oneindige lus) en profileer altijd via GPU Profile Rendering op het apparaat. Dit toont de exacte tekentijd van elk frame en helpt problematische plekken te identificeren.

Veelgestelde vragen

Kan invalidate() worden aangeroepen vanuit onDraw()?

Nee, het aanroepen van invalidate() binnen onDraw() creëert een oneindige hertekeningslus: onDraw() roept invalidate() aan, die opnieuw onDraw() start. Dit leidt tot 100% CPU-belasting en frameverlies. Gebruik animaties via ValueAnimator of Choreographer.

Wat is het verschil tussen invalidate() en postInvalidate()?

invalidate() werkt alleen in de UI-thread en werkt de dirty-vlag onmiddellijk bij. postInvalidate() stuurt een verzoek via Handler naar de UI-thread en kan vanuit elke achtergrondthread worden aangeroepen. Als u in de UI-thread bent — gebruik dan invalidate() voor minimale latentie.

Roept setText() in TextView automatisch invalidate() aan?

Ja, binnen TextView roept de methode setText() invalidate() aan na het bijwerken van de tekst. Als de tekst de afmetingen van de view heeft gewijzigd, wordt aanvullend requestLayout() aangeroepen. De ontwikkelaar hoeft invalidate() niet handmatig aan te roepen bij het werken met standaard widgets.

Hoe beïnvloedt invalidate() de prestaties bij 60 FPS?

Elke invalidate()-aanroep plant hertekening in de volgende Vsync (elke 16 ms). Als onDraw() langer dan 16 ms duurt, vindt frameverlies plaats. Optimaliseer onDraw() — cache Bitmap, vermijd allocaties en gebruik Hardware Acceleration voor GPU-tekening.

Moet invalidate() worden aangeroepen na het wijzigen van Paint-eigenschappen?

Ja, na het wijzigen van Paint-eigenschappen (kleur, dikte, stijl) moet invalidate() worden aangeroepen, omdat View wijzigingen in Paint-objecten niet automatisch volgt. Het systeem weet niet dat Paint is gewijzigd en zal onDraw() niet aanroepen zonder expliciet verzoek.

Samenvatting

  • invalidate() — het belangrijkste mechanisme voor het aanvragen van hertekening van View in Android, werkt asynchroon via dirty-vlag
  • postInvalidate() — threadveilige versie voor aanroep vanuit achtergrondthreads, gebruikt Handler
  • invalidate(Rect) — gedeeltelijke hertekening alleen van het opgegeven gebied, cruciaal voor prestaties bij puntige wijzigingen
  • requestLayout() — start de volledige measure + layout + draw-cyclus, aanzienlijk zwaarder dan invalidate()
  • Choreographer — systeemservice voor synchronisatie met Vsync, aanbevolen voor animaties met invalidate()
  • Hardware Acceleration — GPU-versnelling beschikbaar vanaf API 14, versnelt verwerking van invalidate() voor Canvas API
  • GPU Profile Rendering — profileringsinstrument voor het meten van tekentijd en identificeren van trage onDraw()

We ontwikkelen een mobiele applicatie turnkey

IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.

Bespreek het project

Lees ook