invalidate() — Was es ist, Neuzeichnungsmechanismus und invalidate(Rect)

Autor: IT Sectr Veröffentlicht: 2026-07-20 Lesezeit: 7 Min.

invalidate() ist eine Methode der View-Klasse in Android, die eine Ansicht als neuzeichnungsbedürftig markiert. Der Aufruf von invalidate() löst eine Neuzeichnung der Ansicht im nächsten Bildschirmaktualisierungszyklus aus und ist somit der primäre Mechanismus zur Aktualisierung des visuellen Zustands benutzerdefinierter Komponenten. Laut Android Developers Documentation (2025) wird invalidate() in 90 % der benutzerdefinierten Views verwendet, um Datenänderungen mit der Bildschirmanzeige zu synchronisieren. Die Methode arbeitet asynchron — sie setzt lediglich das dirty-Flag und gibt sofort die Kontrolle zurück.

Wichtigste Punkte

  • invalidate() — eine asynchrone Anfrage zum Neuzeichnen von View in Android, arbeitet über den dirty-Flag-Mechanismus
  • postInvalidate() — Version von invalidate() zum Aufruf aus einem Hintergrundthread, threadsicher
  • invalidate(Rect) — teilweises Neuzeichnen nur des angegebenen Bereichs zur Leistungsoptimierung
  • onDraw() — die Methode, die vom System nach invalidate() aufgerufen wird, ähnlich draw(_:) in iOS
  • invalidate() vs requestLayout() — invalidate() zeichnet den Inhalt neu, requestLayout() berechnet die Geometrie neu

Was ist invalidate() in Android

invalidate() ist eine Methode der Klasse android.view.View, die dem Android-System mitteilt, dass die visuelle Darstellung einer Ansicht veraltet ist. Nach dem Aufruf der Methode markiert das System die Ansicht als dirty und plant ihre Neuzeichnung im nächsten Bildschirmaktualisierungszyklus (normalerweise 16 ms für 60 FPS).

Die Methode invalidate() gibt es in verschiedenen Formen: ohne Parameter (vollständige Neuzeichnung), mit einem Rect-Parameter (teilweise) und mit ltrb-Parametern (left, top, right, bottom). Alle Versionen arbeiten asynchron und müssen vom UI-Thread aus aufgerufen werden. Für Aufrufe aus Hintergrundthreads gibt es postInvalidate().

Wie funktioniert das Neuzeichnen durch invalidate()

Der Neuzeichnungsmechanismus in Android basiert auf ViewRootImpl — einer internen Komponente, die die View-Hierarchie mit der Zeichenoberfläche verbindet. Wenn invalidate() aufgerufen wird, markiert ViewRootImpl den Ansichtsbereich als dirty und sendet eine Neuzeichnungsanfrage über Choreographer — einen Systemdienst, der das Zeichnen mit der Bildwiederholfrequenz synchronisiert.

Der Neuzeichnungszyklus

Choreographer empfängt ein Signal von Vsync und startet einen dreifachen Durchlauf: measure, layout, draw. Allerdings betrifft invalidate() nur die draw-Phase — die measure- und layout-Phasen werden nicht ausgeführt, es sei denn, requestLayout() wurde aufgerufen. Dies ist ein entscheidender Unterschied: invalidate() ist günstiger als requestLayout(), da es die Geometrie nicht neu berechnet.

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

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

        // Diagramm linie zeichnen
        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 diesem Beispiel ruft eine benutzerdefinierte Ansicht zum Zeichnen eines Diagramms invalidate() auf, wenn Daten aktualisiert werden. Das System zeichnet nur diese Ansicht neu, ohne andere Elemente in der Hierarchie zu beeinflussen. onDraw() erhält ein Canvas zum Zeichnen von Linien über Path.

invalidate() vs postInvalidate()

Der Hauptunterschied zwischen invalidate() und postInvalidate() liegt in der Threadsicherheit. invalidate() darf nur vom UI-Thread (Hauptthread) aus aufgerufen werden. postInvalidate() kann von jedem Thread aus aufgerufen werden — es sendet eine Neuzeichnungsanfrage über Handler an den UI-Thread.

Eigenschaftinvalidate()postInvalidate()
Aufruf-ThreadUI-Thread (Hauptthread)Jeder Thread
MechanismusDirekte dirty-Flag-AktualisierungÜber Handler.post() an den UI-Thread
LatenzMinimal, im aktuellen ZyklusBis zum nächsten UI-Thread-Zyklus
LeistungHochGeringer Handler-Overhead
EmpfehlungImmer invalidate() für UI-ThreadNur für Hintergrundthreads

In der Praxis wird postInvalidate() in Szenarien wie Netzwerkdatenladung, Sensorergebnisverarbeitung oder Hintergrundberechnungen verwendet. Wenn Sie sich im UI-Thread befinden — verwenden Sie immer invalidate() für minimale Latenz.

kotlin
    // Vom UI-Thread aufgerufen
view.invalidate()

    // Vom Hintergrundthread aufgerufen
Thread {
    // Schwere Berechnungen
    val result = performHeavyCalculation()
    runOnUiThread {
        updateUi(result)
    }
}.start()

Teilweises Neuzeichnen durch invalidate(Rect)

invalidate(Rect) und invalidate(int l, int t, int r, int b) ermöglichen es, den Neuzeichnungsbereich zu begrenzen. Dies ist für die Leistung entscheidend: Wenn sich nur ein Teil einer Ansicht ändert (z. B. Cursor-Bewegung, Indikator-Änderung), ist es nicht nötig, die gesamte Ansicht neu zu zeichnen.

Das System übergibt das angegebene dirty-Rechteck an onDraw() über canvas.clipBounds. Innerhalb von onDraw() können Sie clipBounds überprüfen und nur innerhalb dieses Bereichs zeichnen, obwohl Android Canvas das Zeichnen außerhalb des dirty-Rechtecks automatisch beschneidet.

kotlin
    // Teilaktualisierung: nur Cursorbereich
private val cursorRect = Rect()

fun moveCursorTo(newX: Int, newY: Int) {
    // Alte Position ungültig machen
    invalidate(cursorRect)

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

    // Neue Position ungültig machen
    invalidate(cursorRect)
}

Ohne teilweises Neuzeichnen würde jede Cursor-Bewegung die gesamte Ansicht neu zeichnen, was bei einem großen Diagramm das Neuzeichnen von Tausenden Pixeln statt einigen Dutzend bedeutet. invalidate(Rect) ist eine essentielle Technik für Editoren, Zeichenflächen und animierte Komponenten.

invalidate() vs requestLayout(): Was ist der Unterschied

Ein häufiger Fehler ist der Aufruf von requestLayout() dort, wo invalidate() ausreichen würde, und umgekehrt. Der Unterschied ist grundlegend: invalidate() betrifft nur die draw-Phase, während requestLayout() einen vollständigen measure → layout → draw-Zyklus auslöst.

Aspektinvalidate()requestLayout()
ZyklusphasenNur drawmeasure + layout + draw
Wann verwendenNur die Darstellung ändert sich (Farbe, Text, Grafik)Größe oder Position der Ansicht ändert sich
LeistungLeicht — nur NeuzeichnenSchwer — Neuberechnung der Hierarchie
Auswirkung auf HierarchieNur die aktuelle AnsichtKann Elterncontainer beeinflussen

Wenn Sie Text in einem TextView ändern, ist invalidate() ausreichend, da sich die Größe der Ansicht nicht ändert. Wenn der Text in eine neue Zeile umbrechen und die Höhe vergrößern kann, ist requestLayout() erforderlich. Android Lint hilft, solche Fehler durch Leistungsregeln zu verfolgen.

Leistungsoptimierung von invalidate()

Übermäßige invalidate()-Aufrufe sind eine der Hauptursachen für schlechte Leistung benutzerdefinierter Views in Android. Betrachten wir Optimierungstechniken.

Minimieren Sie die Aufruffrequenz

Wenn Daten mit hoher Frequenz (Sensoren, Animationen, Video) aktualisiert werden, rufen Sie invalidate() nicht bei jeder Änderung auf. Verwenden Sie ValueAnimator oder Choreographer.FrameCallback zur Synchronisation mit der Bildwiederholfrequenz. Dies stellt sicher, dass invalidate() nicht mehr als einmal pro Frame aufgerufen wird.

Verwenden Sie Hardwarebeschleunigung

Seit API 14 unterstützt Android Hardwarebeschleunigung über GPU. Wenn Ihre benutzerdefinierte Ansicht nur Canvas API (drawRect, drawCircle, drawPath) verwendet, funktioniert die Beschleunigung transparent. Für DisplayList-kompatible Operationen wird invalidate() deutlich schneller verarbeitet.

kotlin
// Choreographer für Vsync-Synchronisation verwenden
private val frameCallback = Choreographer.FrameCallback { frameTimeNanos ->
    updateAnimation(frameTimeNanos)
    invalidate()
    Choreographer.getInstance().postFrameCallback(this)
}

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

Verwenden Sie invalidate(Rect) für gezielte Aktualisierungen, vermeiden Sie den Aufruf von invalidate() aus onDraw() (Endlosschleife), und profilieren Sie immer über GPU Profile Rendering auf einem Gerät. Dies zeigt die genaue Renderzeit jedes Frames und hilft, Problembereiche zu identifizieren.

Häufig gestellte Fragen

Kann invalidate() von onDraw() aus aufgerufen werden?

Nein, der Aufruf von invalidate() innerhalb von onDraw() erzeugt eine Endlosschleife des Neuzeichnens: onDraw() ruft invalidate() auf, was wiederum onDraw() auslöst. Dies führt zu 100 % CPU-Auslastung und Frame-Einbrüchen. Verwenden Sie Animationen über ValueAnimator oder Choreographer.

Worin unterscheidet sich invalidate() von postInvalidate()?

invalidate() funktioniert nur im UI-Thread und aktualisiert das dirty-Flag sofort. postInvalidate() sendet eine Anfrage über Handler an den UI-Thread und kann von jedem Hintergrundthread aus aufgerufen werden. Wenn Sie im UI-Thread sind — verwenden Sie invalidate() für minimale Latenz.

Ruft setText() in TextView automatisch invalidate() auf?

Ja, intern ruft die Methode setText() von TextView nach der Textaktualisierung invalidate() auf. Wenn der Text die Abmessungen der Ansicht ändert, wird zusätzlich requestLayout() aufgerufen. Entwickler müssen invalidate() bei der Arbeit mit Standard-Widgets nicht manuell aufrufen.

Wie beeinflusst invalidate() die Leistung bei 60 FPS?

Jeder invalidate()-Aufruf plant eine Neuzeichnung im nächsten Vsync (alle 16 ms). Wenn onDraw() länger als 16 ms dauert, kommt es zu Frame-Einbrüchen. Optimieren Sie onDraw() — cachen Sie Bitmaps, vermeiden Sie Allokationen und verwenden Sie Hardwarebeschleunigung für GPU-Rendering.

Muss invalidate() nach Änderung von Paint-Eigenschaften aufgerufen werden?

Ja, nach Änderung von Paint-Eigenschaften (Farbe, Dicke, Stil) müssen Sie invalidate() aufrufen, da die View Änderungen an Paint-Objekten nicht automatisch verfolgt. Das System weiß nicht, dass sich Paint geändert hat, und wird onDraw() ohne explizite Anfrage nicht aufrufen.

Zusammenfassung

  • invalidate() — der primäre Mechanismus zur Anforderung von View-Neuzeichnung in Android, arbeitet asynchron über das dirty-Flag
  • postInvalidate() — threadsichere Version für Aufrufe aus Hintergrundthreads, verwendet Handler
  • invalidate(Rect) — teilweises Neuzeichnen nur des angegebenen Bereichs, entscheidend für die Leistung bei gezielten Änderungen
  • requestLayout() — löst einen vollständigen measure + layout + draw-Zyklus aus, deutlich schwerer als invalidate()
  • Choreographer — Systemdienst zur Vsync-Synchronisation, empfohlen für Animationen mit invalidate()
  • Hardware Acceleration — GPU-Beschleunigung verfügbar seit API 14, beschleunigt invalidate()-Verarbeitung für Canvas API
  • GPU Profile Rendering — Profiling-Tool zur Messung der Renderzeit und Identifizierung langsamer onDraw()-Methoden

Wir entwickeln eine mobile Applikation schlüsselfertig

IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.

Projekt besprechen

Lesen Sie auch