invalidate() — Nedir, yeniden çizim mekanizması ve invalidate(Rect)

Yazar: IT Sectr Yayınlanma: 2026-07-20 Okuma süresi: 7 dk

invalidate(), Android'de View sınıfının bir yöntemidir ve bir görünümü yeniden çizilmesi gereken olarak işaretler. invalidate() çağrısı, sonraki ekran yenileme döngüsünde görünümün yeniden çizilmesini tetikler ve bu da onu özel bileşenlerin görsel durumunu güncellemenin birincil mekanizması haline getirir. Android Developers Documentation'a (2025) göre, invalidate() özel View'lerin %90'ında veri değişikliklerini ekran görüntüsüyle senkronize etmek için kullanılır. Yöntem asenkron olarak çalışır — yalnızca dirty bayrağını ayarlar ve kontrolü hemen geri verir.

Önemli Noktalar

  • invalidate() — Android'de View yeniden çizimi için asenkron bir istek, dirty bayrak mekanizmasıyla çalışır
  • postInvalidate() — arka plan iş parçacığından çağırmak için invalidate() sürümü, iş parçacığı güvenli
  • invalidate(Rect) — performans optimizasyonu için yalnızca belirtilen alanın kısmi yeniden çizimi
  • onDraw() — invalidate()'den sonra sistem tarafından çağrılan yöntem, iOS'taki draw(_:)'ya benzer
  • invalidate() vs requestLayout() — invalidate() içeriği yeniden çizer, requestLayout() geometriyi yeniden hesaplar

Android'de invalidate() Nedir

invalidate(), android.view.View sınıfının bir yöntemidir ve Android sistemine bir görünümün görsel temsilinin güncelliğini yitirdiğini bildirir. Yöntem çağrıldıktan sonra sistem, görünümü dirty olarak işaretler ve sonraki ekran yenileme döngüsünde (genellikle 60 FPS için 16 ms) yeniden çizimini planlar.

invalidate() yöntemi çeşitli biçimlerde gelir: parametresiz (tam yeniden çizim), Rect parametreli (kısmi) ve ltrb parametreli (left, top, right, bottom). Tüm sürümler asenkron çalışır ve UI iş parçacığından çağrılmalıdır. Arka plan iş parçacıklarından çağırmak için postInvalidate() bulunur.

invalidate() ile Yeniden Çizim Nasıl Çalışır

Android'de yeniden çizim mekanizması ViewRootImpl'a dayanır — View Hiyerarşisini çizim için Surface'e bağlayan dahili bir bileşen. invalidate() çağrıldığında, ViewRootImpl görünüm alanını dirty olarak işaretler ve Choreographer aracılığıyla bir yeniden çizim isteği gönderir — çizimi ekran yenileme hızıyla senkronize eden bir sistem hizmeti.

Yeniden Çizim Döngüsü

Choreographer, Vsync'ten bir sinyal alır ve üç aşamalı bir süreç başlatır: measure, layout, draw. Ancak invalidate() yalnızca draw aşamasını etkiler — requestLayout() çağrılmadıkça measure ve layout aşamaları yürütülmez. Bu önemli bir farktır: invalidate(), geometriyi yeniden hesaplamadığı için requestLayout()'tan daha hafiftir.

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() // Yeniden çizim isteği
    }

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

        // Grafik çizgisi çiziliyor
        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)
    }
}

Bu örnekte, bir grafik çizmek için özel bir View, veriler güncellendiğinde invalidate() çağrısı yapar. Sistem, hiyerarşideki diğer öğeleri etkilemeden yalnızca bu View'i yeniden çizer. onDraw(), Path aracılığıyla çizgiler çizmek için bir Canvas alır.

invalidate() vs postInvalidate()

invalidate() ve postInvalidate() arasındaki temel fark, iş parçacığı güvenliğinde yatar. invalidate() yalnızca UI iş parçacığından (ana iş parçacığı) çağrılmalıdır. postInvalidate() herhangi bir iş parçacığından çağrılabilir — Handler aracılığıyla UI iş parçacığına bir yeniden çizim isteği gönderir.

Özellikinvalidate()postInvalidate()
Çağrı İş ParçacığıUI iş parçacığı (ana iş parçacığı)Herhangi bir iş parçacığı
MekanizmaDoğrudan dirty bayrak güncellemesiHandler.post() ile UI iş parçacığına
GecikmeMinimum, mevcut döngüdeSonraki UI iş parçacığı döngüsüne kadar
PerformansYüksekHandler'da hafif ek yük
ÖneriUI iş parçacığı için her zaman invalidate()Yalnızca arka plan iş parçacıkları için

Pratikte, postInvalidate() ağ verisi yükleme, sensör sonuçları işleme veya arka plan hesaplamaları senaryolarında kullanılır. UI iş parçacığındaysanız — minimum gecikme için her zaman invalidate() kullanın.

kotlin
    // UI iş parçacığından çağrıldı
view.invalidate()

    // Arka plan iş parçacığından çağrıldı
Thread {
    // Ağır hesaplamalar
    val result = performHeavyCalculation()
    runOnUiThread {
        updateUi(result)
    }
}.start()

invalidate(Rect) ile Kısmi Yeniden Çizim

invalidate(Rect) ve invalidate(int l, int t, int r, int b), yeniden çizim alanını sınırlamaya olanak tanır. Bu, performans için kritiktir: Bir View'in yalnızca bir kısmı değiştiğinde (örneğin, imleç hareketi, gösterge değişimi), tüm görünümü yeniden çizmeye gerek yoktur.

Sistem, belirtilen dirty dikdörtgeni onDraw()'a canvas.clipBounds aracılığıyla iletir. onDraw() içinde clipBounds'ı kontrol edebilir ve yalnızca bu alan içinde çizim yapabilirsiniz, ancak Android Canvas, dirty dikdörtgenin dışındaki çizimi otomatik olarak kırpar.

kotlin
    // Kısmi güncelleme: yalnızca imleç alanı
private val cursorRect = Rect()

fun moveCursorTo(newX: Int, newY: Int) {
    // Eski konumu geçersiz kıl
    invalidate(cursorRect)

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

    // Yeni konumu geçersiz kıl
    invalidate(cursorRect)
}

Kısmi yeniden çizim olmadan, her imleç hareketi tüm View'i yeniden çizerdi ve bu, büyük bir grafik için birkaç düzine yerine binlerce pikselin yeniden çizilmesi anlamına gelir. invalidate(Rect), düzenleyiciler, çizim tuvalleri ve animasyonlu bileşenler için gerekli bir tekniktir.

invalidate() vs requestLayout(): Fark Nedir

Yaygın bir hata, invalidate()'in yeterli olacağı yerde requestLayout()'u çağırmak ve bunun tersidir. Fark temeldir: invalidate() yalnızca draw aşamasını etkilerken, requestLayout() tam bir measure → layout → draw döngüsünü tetikler.

Yöninvalidate()requestLayout()
Döngü AşamalarıYalnızca drawmeasure + layout + draw
Ne Zaman KullanılırYalnızca işleme değişir (renk, metin, grafik)Görünümün boyutu veya konumu değişir
PerformansHafif — yalnızca yeniden çizimAğır — hiyerarşiyi yeniden hesaplar
Hiyerarşi EtkisiYalnızca mevcut ViewÜst kapsayıcıları etkileyebilir

Bir TextView'de metin değiştirirseniz, View boyutu değişmediği için invalidate() yeterlidir. Metin yeni bir satıra geçip yüksekliği artırabiliyorsa, requestLayout() gereklidir. Android Lint, performans kuralları aracılığıyla bu tür hataları izlemeye yardımcı olur.

invalidate() Performans Optimizasyonu

Aşırı invalidate() çağrıları, Android'de özel View performansının düşük olmasının ana nedenlerinden biridir. Optimizasyon tekniklerine bakalım.

Çağrı Sıklığını En Aza indirin

Veriler yüksek frekansta (sensörler, animasyonlar, video) güncelleniyorsa, her değişiklikte invalidate() çağırmayın. Ekran yenileme hızıyla senkronize olmak için ValueAnimator veya Choreographer.FrameCallback kullanın. Bu, invalidate()'in kare başına bir defadan fazla çağrılmamasını sağlar.

Donanım Hızlandırmayı Kullanın

API 14'ten itibaren Android, GPU aracılığıyla donanım hızlandırmayı destekler. Özel View'iniz yalnızca Canvas API (drawRect, drawCircle, drawPath) kullanıyorsa, hızlandırma şeffaf bir şekilde çalışır. DisplayList uyumlu işlemler için invalidate() önemli ölçüde daha hızlı işlenir.

kotlin
// Vsync senkronizasyonu için Choreographer kullanma
private val frameCallback = Choreographer.FrameCallback { frameTimeNanos ->
    updateAnimation(frameTimeNanos)
    invalidate()
    Choreographer.getInstance().postFrameCallback(this)
}

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

Hedeflenen güncellemeler için invalidate(Rect) kullanın, onDraw()'dan invalidate() çağırmaktan kaçının (sonsuz döngü) ve her zaman bir cihazda GPU Profile Rendering ile profil oluşturun. Bu, her karenin tam işleme süresini gösterecek ve sorunlu alanları belirlemeye yardımcı olacaktır.

Sıkça Sorulan Sorular

onDraw()'dan invalidate() çağrılabilir mi?

Hayır, onDraw() içinde invalidate() çağırmak sonsuz bir yeniden çizim döngüsü oluşturur: onDraw() invalidate()'i çağırır, bu da tekrar onDraw()'u tetikler. Bu, %100 CPU kullanımına ve kare düşüşlerine yol açar. ValueAnimator veya Choreographer aracılığıyla animasyonlar kullanın.

invalidate() postInvalidate()'den nasıl farklıdır?

invalidate() yalnızca UI iş parçacığında çalışır ve dirty bayrağını hemen günceller. postInvalidate(), Handler aracılığıyla UI iş parçacığına bir istek gönderir ve herhangi bir arka plan iş parçacığından çağrılabilir. UI iş parçacığındaysanız — minimum gecikme için invalidate() kullanın.

TextView'de setText() otomatik olarak invalidate() çağırır mı?

Evet, dahili olarak TextView'in setText() yöntemi, metni güncelledikten sonra invalidate() çağırır. Metin görünümün boyutlarını değiştirirse, ayrıca requestLayout() da çağrılır. Standart widget'larla çalışırken geliştiricilerin manuel olarak invalidate() çağırması gerekmez.

60 FPS'de invalidate() performansı nasıl etkiler?

Her invalidate() çağrısı, sonraki Vsync'te (her 16 ms'de bir) yeniden çizim planlar. onDraw() 16 ms'den uzun sürerse, kare düşüşleri meydana gelir. onDraw()'ı optimize edin — Bitmap'leri önbelleğe alın, ayırmalardan kaçının ve GPU işlemesi için donanım hızlandırmayı kullanın.

Paint özelliklerini değiştirdikten sonra invalidate() çağırmak gerekli mi?

Evet, Paint özelliklerini (renk, kalınlık, stil) değiştirdikten sonra invalidate() çağırmalısınız, çünkü View, Paint nesnelerindeki değişiklikleri otomatik olarak izlemez. Sistem, Paint'in değiştiğini bilmez ve açık bir istek olmadan onDraw()'u çağırmaz.

Özet

  • invalidate() — Android'de View yeniden çizimi talep etmenin birincil mekanizması, dirty bayrak aracılığıyla asenkron çalışır
  • postInvalidate() — arka plan iş parçacıklarından çağırmak için iş parçacığı güvenli sürüm, Handler kullanır
  • invalidate(Rect) — yalnızca belirtilen alanın kısmi yeniden çizimi, hedeflenen değişiklikler için performans açısından kritik
  • requestLayout() — tam measure + layout + draw döngüsünü tetikler, invalidate()'ten önemli ölçüde ağır
  • Choreographer — Vsync senkronizasyonu için sistem hizmeti, invalidate() ile animasyonlar için önerilir
  • Hardware Acceleration — API 14'ten itibaren kullanılabilen GPU hızlandırma, Canvas API için invalidate() işlemesini hızlandırır
  • GPU Profile Rendering — işleme süresini ölçmek ve yavaş onDraw() yöntemlerini belirlemek için profil oluşturma aracı

Anahtar teslim bir mobil uygulama geliştireceğiz

IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.

Projeyi tartış

Ayrıca okuyun