invalidate() — vad är det, omritningsmekanism och invalidate(Rect)

Författare: IT Sectr Publicerad: 2026-07-20 Lästid: 7 min

invalidate() — är en metod i klassen View i Android som markerar en vy som i behov av omritning. Anrop av invalidate() leder till omritning av vyn i den närmaste skärmuppdateringscykeln, vilket gör det till den huvudsakliga mekanismen för att uppdatera visuellt tillstånd för anpassade komponenter. Enligt Android Developers Documentation (2025) används invalidate() i 90% av anpassade View för att synkronisera dataändringar med visning på skärmen. Metoden fungerar asynkront — den sätter bara dirty-flaggan och återger omedelbart kontrollen.

Huvudpunkter

  • invalidate() — asynkron begäran om omritning av View i Android, fungerar via dirty flag-mekanism
  • postInvalidate() — version av invalidate() för anrop från bakgrundstråd, trådsäker
  • invalidate(Rect) — partiell omritning endast av angivet område för prestandaoptimering
  • onDraw() — metod som anropas av systemet efter invalidate(), analog med draw(_:) i iOS
  • invalidate() vs requestLayout() — invalidate() ritar om innehåll, requestLayout() räknar om geometri

Vad är invalidate() i Android

invalidate() — är en metod i klassen android.view.View som informerar Android-systemet att den visuella representationen av vyn är föråldrad. Efter metodanropet markerar systemet vyn som dirty och schemalägger dess omritning i den närmaste skärmuppdateringscykeln (vanligtvis 16 ms för 60 FPS).

Metoden invalidate() tar olika former: utan parametrar (fullständig omritning), med parametern Rect (partiell) och med parametrarna ltrb (left, top, right, bottom). Alla versioner fungerar asynkront och kan anropas från UI-tråden. För anrop från bakgrundstrådar finns postInvalidate().

Hur fungerar omritning via invalidate()

Omritningsmekanismen i Android är baserad på ViewRootImpl — en intern komponent som kopplar View Hierarchy till Surface för ritning. När invalidate() anropas markerar ViewRootImpl vyns område som dirty och skickar en begäran om omritning via Choreographer — en systemtjänst som synkroniserar ritning med skärmuppdateringsfrekvensen.

Omritningscykel

Choreographer tar emot signal från Vsync och startar en trippel genomgång: measure, layout, draw. Dock påverkar invalidate() endast draw-fasen — measure- och layout-faserna utförs inte om inte requestLayout() har anropats. Detta är den viktigaste skillnaden: invalidate() är billigare än requestLayout() eftersom den inte räknar om geometrin.

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() // Omritningsbegäran
    }

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

        // Rita graflinje
        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)
    }
}

I detta exempel anropar en anpassad View för ritning av graf invalidate() vid uppdatering av data. Systemet ritar bara om denna View, utan att påverka övriga element i hierarkin. onDraw() får Canvas för ritning av linjer via Path.

invalidate() vs postInvalidate()

Den huvudsakliga skillnaden mellan invalidate() och postInvalidate() är trådsäkerheten. invalidate() får endast anropas från UI-tråden (huvudtråden). postInvalidate() kan anropas från vilken tråd som helst — via Handler skickar den en begäran om omritning till UI-tråden.

Egenskapinvalidate()postInvalidate()
AnropstrådUI-tråd (huvudtråd)Vilken tråd som helst
MekanismDirekt uppdatering av dirty-flaggaVia Handler.post() till UI-tråden
LatensMinimal, i nuvarande cykelTill nästa cykel av UI-tråden
PrestandaHögLiten overhead på Handler
RekommendationFör UI-tråd alltid invalidate()Endast för bakgrundstrådar

I praktiken används postInvalidate() i scenarier med nätverksdataladdning, bearbetning av sensorresultat eller bakgrundsberäkningar. Om du är i UI-tråden — använd alltid invalidate() för minimal latens.

kotlin
    // Anropad från UI-tråd
view.invalidate()

    // Anropad från bakgrundstråd
Thread {
    // Tunga beräkningar
    val result = performHeavyCalculation()
    runOnUiThread {
        updateUi(result)
    }
}.start()

Partiell omritning via invalidate(Rect)

invalidate(Rect) och invalidate(int l, int t, int r, int b) gör det möjligt att begränsa omritningsområdet. Detta är kritiskt för prestanda: vid uppdatering av endast en del av View (t.ex. cursorrörelse, indikatorändring) är det meningslöst att rita om hela vyn.

Systemet skickar den angivna dirty-rektangeln till onDraw() via canvas.clipBounds. Inuti onDraw() kan clipBounds kontrolleras och endast ritas inom detta område, även om Android Canvas automatiskt beskär ritning utanför dirty-rektangeln.

kotlin
    // Partiell uppdatering: endast cursorområde
private val cursorRect = Rect()

fun moveCursorTo(newX: Int, newY: Int) {
    // Ogiltigförklara gammal position
    invalidate(cursorRect)

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

    // Ogiltigförklara ny position
    invalidate(cursorRect)
}

Utan partiell omritning skulle varje cursorrörelse rita om hela View, vilket för en stor graf innebär omritning av tusentals pixlar istället för några dussin. invalidate(Rect) — en obligatorisk teknik för redigerare, ritdukar och animerade komponenter.

invalidate() vs requestLayout(): vad är skillnaden

Ett av de vanliga misstagen är att anropa requestLayout() där invalidate() räcker, och tvärtom. Skillnaden är fundamental: invalidate() påverkar endast draw-fasen, medan requestLayout() startar hela measure → layout → draw-cykeln.

Aspektinvalidate()requestLayout()
CyklusfaserEndast drawmeasure + layout + draw
När användaEndast ritning ändras (färg, text, grafik)Storlek eller position på vyn ändras
PrestandaLätt — endast omritningTung — omräkning av hierarki
Påverkan på hierarkiEndast aktuell vyKan påverka föräldracontainrar

Om du ändrar text i TextView — räcker invalidate(), eftersom vyns storlek inte ändras. Om texten kan flyttas till en ny rad och öka höjden — behövs requestLayout(). Android Lint hjälper till att spåra sådana fel genom prestandaregler.

Prestandaoptimering av invalidate()

Överdrivna invalidate()-anrop — en av de främsta orsakerna till låg prestanda för anpassade View i Android. Låt oss titta på optimeringstekniker.

Minimera anropsfrekvensen

Om data uppdateras med hög frekvens (sensorer, animation, video), anropa inte invalidate() vid varje ändring. Använd ValueAnimator eller Choreographer.FrameCallback för synkronisering med skärmuppdateringsfrekvensen. Detta garanterar att invalidate() anropas inte mer än en gång per bildruta.

Använd Hardware Acceleration

Från API 14 stöder Android hårdvaruacceleration via GPU. Om din anpassade View endast använder Canvas API (drawRect, drawCircle, drawPath), fungerar accelerationen transparent. För DisplayList-kompatibla operationer bearbetas invalidate() betydligt snabbare.

kotlin
// Använda Choreographer för Vsync-synkronisering
private val frameCallback = Choreographer.FrameCallback { frameTimeNanos ->
    updateAnimation(frameTimeNanos)
    invalidate()
    Choreographer.getInstance().postFrameCallback(this)
}

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

Använd invalidate(Rect) för punktuppdateringar, undvik att anropa invalidate() från onDraw() (oändlig loop) och profilera alltid via GPU Profile Rendering på enheten. Detta visar den exakta ritningstiden för varje bildruta och hjälper att identifiera problematiska områden.

Vanliga frågor

Kan invalidate() anropas från onDraw()?

Nej, anrop av invalidate() inuti onDraw() skapar en oändlig omritningsloop: onDraw() anropar invalidate(), som igen startar onDraw(). Detta leder till 100% CPU-belastning och tappade bildrutor. Använd animationer via ValueAnimator eller Choreographer.

Hur skiljer sig invalidate() från postInvalidate()?

invalidate() fungerar endast i UI-tråden och uppdaterar dirty-flaggan omedelbart. postInvalidate() skickar en begäran via Handler till UI-tråden och kan anropas från vilken bakgrundstråd som helst. Om du är i UI-tråden — använd invalidate() för minimal latens.

Anropar setText() i TextView automatiskt invalidate()?

Ja, inuti TextView anropar metoden setText() invalidate() efter uppdatering av texten. Om texten har ändrat vyns dimensioner, anropas dessutom requestLayout(). Utvecklaren behöver inte manuellt anropa invalidate() vid arbete med standardwidgetar.

Hur påverkar invalidate() prestanda vid 60 FPS?

Varje invalidate()-anrop schemalägger omritning i nästa Vsync (var 16:e ms). Om onDraw() tar längre än 16 ms, sker tappade bildrutor. Optimera onDraw() — cacha Bitmap, undvik allokeringar och använd Hardware Acceleration för GPU-ritning.

Behöver invalidate() anropas efter ändring av Paint-egenskaper?

Ja, efter ändring av Paint-egenskaper (färg, tjocklek, stil) måste invalidate() anropas, eftersom View inte automatiskt spårar ändringar i Paint-objekt. Systemet vet inte att Paint har ändrats och kommer inte att anropa onDraw() utan explicit begäran.

Sammanfattning

  • invalidate() — den huvudsakliga mekanismen för begäran om omritning av View i Android, fungerar asynkront via dirty-flagga
  • postInvalidate() — trådsäker version för anrop från bakgrundstrådar, använder Handler
  • invalidate(Rect) — partiell omritning endast av angivet område, kritisk för prestanda vid punktförändringar
  • requestLayout() — startar hela measure + layout + draw-cykeln, betydligt tyngre än invalidate()
  • Choreographer — systemtjänst för synkronisering med Vsync, rekommenderas för animationer med invalidate()
  • Hardware Acceleration — GPU-acceleration tillgänglig från API 14, snabbar upp bearbetning av invalidate() för Canvas API
  • GPU Profile Rendering — profileringsverktyg för att mäta ritningstid och identifiera långsamma onDraw()

Vi utvecklar en mobil applikation nyckelfärdigt

IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.

Diskutera projektet

Läs också