invalidate() — apa itu, mekanisme penggambaran ulang dan invalidate(Rect)

Penulis: IT Sectr Diterbitkan: 2026-07-20 Waktu membaca: 7 mnt

invalidate() — adalah metode kelas View di Android yang menandai tampilan sebagai memerlukan penggambaran ulang. Pemanggilan invalidate() menyebabkan penggambaran ulang tampilan dalam siklus pembaruan layar terdekat, menjadikannya mekanisme utama untuk memperbarui status visual komponen kustom. Menurut Android Developers Documentation (2025), invalidate() digunakan dalam 90% View kustom untuk menyinkronkan perubahan data dengan tampilan di layar. Metode ini bekerja secara asinkron — ia hanya mengatur flag dirty dan segera mengembalikan kendali.

Poin Utama

  • invalidate() — permintaan asinkron untuk penggambaran ulang View di Android, bekerja melalui mekanisme dirty flag
  • postInvalidate() — versi invalidate() untuk pemanggilan dari thread latar, aman untuk thread
  • invalidate(Rect) — penggambaran ulang parsial hanya area yang ditentukan untuk optimalisasi kinerja
  • onDraw() — metode yang dipanggil oleh sistem setelah invalidate(), analog dengan draw(_:) di iOS
  • invalidate() vs requestLayout() — invalidate() menggambar ulang konten, requestLayout() menghitung ulang geometri

Apa itu invalidate() di Android

invalidate() — adalah metode dari kelas android.view.View yang memberi tahu sistem Android bahwa representasi visual tampilan sudah usang. Setelah pemanggilan metode, sistem menandai tampilan sebagai dirty dan menjadwalkan penggambaran ulangnya dalam siklus pembaruan layar terdekat (biasanya 16 ms untuk 60 FPS).

Metode invalidate() mengambil berbagai bentuk: tanpa parameter (penggambaran ulang penuh), dengan parameter Rect (parsial) dan dengan parameter ltrb (left, top, right, bottom). Semua versi bekerja secara asinkron dan dapat dipanggil dari thread UI. Untuk pemanggilan dari thread latar ada postInvalidate().

Bagaimana cara kerja penggambaran ulang melalui invalidate()

Mekanisme penggambaran ulang di Android didasarkan pada ViewRootImpl — komponen internal yang menghubungkan View Hierarchy dengan Surface untuk menggambar. Ketika invalidate() dipanggil, ViewRootImpl menandai area tampilan sebagai dirty dan mengirim permintaan penggambaran ulang melalui Choreographer — layanan sistem yang menyinkronkan penggambaran dengan frekuensi pembaruan layar.

Siklus penggambaran ulang

Choreographer menerima sinyal dari Vsync dan menjalankan tiga kali lintasan: measure, layout, draw. Namun invalidate() hanya mempengaruhi fase draw — fase measure dan layout tidak dijalankan kecuali requestLayout() dipanggil. Ini adalah perbedaan kunci: invalidate() lebih ringan dari requestLayout() karena tidak menghitung ulang geometri.

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() // Permintaan penggambaran ulang
    }

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

        // Menggambar garis grafik
        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)
    }
}

Dalam contoh ini, View kustom untuk menggambar grafik memanggil invalidate() saat memperbarui data. Sistem hanya menggambar ulang View ini, tanpa mempengaruhi elemen hierarki lainnya. onDraw() menerima Canvas untuk menggambar garis melalui Path.

invalidate() vs postInvalidate()

Perbedaan utama antara invalidate() dan postInvalidate() adalah keamanan thread. invalidate() hanya boleh dipanggil dari thread UI (thread utama). postInvalidate() dapat dipanggil dari thread mana pun — melalui Handler ia mengirim permintaan penggambaran ulang ke thread UI.

Karakteristikinvalidate()postInvalidate()
Thread pemanggilanThread UI (thread utama)Thread mana pun
MekanismePembaruan langsung dirty flagMelalui Handler.post() ke thread UI
LatensiMinimal, dalam siklus saat iniSampai siklus thread UI berikutnya
KinerjaTinggiOverhead kecil pada Handler
RekomendasiUntuk thread UI selalu invalidate()Hanya untuk thread latar

Dalam praktiknya, postInvalidate() digunakan dalam skenario pemuatan data dari jaringan, pemrosesan hasil sensor atau perhitungan latar. Jika Anda berada di thread UI — selalu gunakan invalidate() untuk latensi minimal.

kotlin
    // Dipanggil dari thread UI
view.invalidate()

    // Dipanggil dari thread latar
Thread {
    // Perhitungan berat
    val result = performHeavyCalculation()
    runOnUiThread {
        updateUi(result)
    }
}.start()

Penggambaran ulang parsial melalui invalidate(Rect)

invalidate(Rect) dan invalidate(int l, int t, int r, int b) memungkinkan membatasi area penggambaran ulang. Ini sangat penting untuk kinerja: saat memperbarui hanya sebagian View (misalnya, pergerakan kursor, perubahan indikator) tidak ada gunanya menggambar ulang seluruh tampilan.

Sistem meneruskan persegi panjang dirty yang ditentukan ke onDraw() melalui canvas.clipBounds. Di dalam onDraw() dapat diperiksa clipBounds dan menggambar hanya dalam batas area ini, meskipun Android Canvas secara otomatis memotong penggambaran di luar persegi panjang dirty.

kotlin
    // Pembaruan parsial: hanya area kursor
private val cursorRect = Rect()

fun moveCursorTo(newX: Int, newY: Int) {
    // Invalidasi posisi lama
    invalidate(cursorRect)

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

    // Invalidasi posisi baru
    invalidate(cursorRect)
}

Tanpa penggambaran ulang parsial, setiap pergerakan kursor akan menggambar ulang seluruh View, yang untuk grafik besar berarti menggambar ulang ribuan piksel alih-alih beberapa puluh. invalidate(Rect) — teknik wajib untuk editor, kanvas gambar, dan komponen animasi.

invalidate() vs requestLayout(): apa perbedaannya

Salah satu kesalahan umum adalah memanggil requestLayout() di mana invalidate() sudah cukup, dan sebaliknya. Perbedaannya fundamental: invalidate() hanya mempengaruhi fase draw, sedangkan requestLayout() menjalankan siklus lengkap measure → layout → draw.

Aspekinvalidate()requestLayout()
Fase siklusHanya drawmeasure + layout + draw
Kapan digunakanHanya penggambaran yang berubah (warna, teks, grafis)Ukuran atau posisi tampilan berubah
KinerjaRingan — hanya penggambaran ulangBerat — perhitungan ulang hierarki
Dampak pada hierarkiHanya tampilan saat iniDapat mempengaruhi kontainer induk

Jika Anda mengubah teks di TextView — invalidate() sudah cukup, karena ukuran tampilan tidak berubah. Jika teks dapat pindah ke baris baru dan menambah tinggi — diperlukan requestLayout(). Android Lint membantu melacak kesalahan semacam itu melalui aturan kinerja.

Optimalisasi kinerja invalidate()

Panggilan invalidate() yang berlebihan — salah satu penyebab utama kinerja rendah View kustom di Android. Mari kita lihat teknik optimalisasi.

Minimalkan frekuensi panggilan

Jika data diperbarui dengan frekuensi tinggi (sensor, animasi, video), jangan panggil invalidate() pada setiap perubahan. Gunakan ValueAnimator atau Choreographer.FrameCallback untuk sinkronisasi dengan frekuensi pembaruan layar. Ini menjamin bahwa invalidate() dipanggil tidak lebih dari sekali per frame.

Gunakan Hardware Acceleration

Sejak API 14 Android mendukung percepatan perangkat keras melalui GPU. Jika View kustom Anda hanya menggunakan Canvas API (drawRect, drawCircle, drawPath), percepatan bekerja secara transparan. Untuk operasi yang kompatibel dengan DisplayList, invalidate() diproses secara signifikan lebih cepat.

kotlin
// Menggunakan Choreographer untuk sinkronisasi Vsync
private val frameCallback = Choreographer.FrameCallback { frameTimeNanos ->
    updateAnimation(frameTimeNanos)
    invalidate()
    Choreographer.getInstance().postFrameCallback(this)
}

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

Gunakan invalidate(Rect) untuk pembaruan titik, hindari memanggil invalidate() dari onDraw() (loop tak terbatas), dan selalu buat profil melalui GPU Profile Rendering pada perangkat. Ini akan menunjukkan waktu penggambaran yang tepat dari setiap frame dan membantu mengidentifikasi tempat-tempat bermasalah.

Pertanyaan yang Sering Diajukan

Bisakah invalidate() dipanggil dari onDraw()?

Tidak, memanggil invalidate() di dalam onDraw() menciptakan loop penggambaran ulang tak terbatas: onDraw() memanggil invalidate(), yang kembali menjalankan onDraw(). Ini menyebabkan beban CPU 100% dan penurunan frame. Gunakan animasi melalui ValueAnimator atau Choreographer.

Apa perbedaan invalidate() dengan postInvalidate()?

invalidate() hanya bekerja di thread UI dan memperbarui dirty flag segera. postInvalidate() mengirim permintaan melalui Handler ke thread UI dan dapat dipanggil dari thread latar mana pun. Jika Anda di thread UI — gunakan invalidate() untuk latensi minimal.

Apakah setText() di TextView secara otomatis memanggil invalidate()?

Ya, di dalam TextView metode setText() memanggil invalidate() setelah memperbarui teks. Jika teks telah mengubah dimensi tampilan, secara tambahan requestLayout() dipanggil. Pengembang tidak perlu memanggil invalidate() secara manual saat bekerja dengan widget standar.

Bagaimana invalidate() mempengaruhi kinerja pada 60 FPS?

Setiap panggilan invalidate() menjadwalkan penggambaran ulang pada Vsync berikutnya (setiap 16 ms). Jika onDraw() berjalan lebih dari 16 ms, terjadi penurunan frame. Optimalkan onDraw() — cache Bitmap, hindari alokasi, dan gunakan Hardware Acceleration untuk penggambaran GPU.

Apakah perlu memanggil invalidate() setelah mengubah properti Paint?

Ya, setelah mengubah properti Paint (warna, ketebalan, gaya) perlu memanggil invalidate(), karena View tidak melacak perubahan objek Paint secara otomatis. Sistem tidak tahu bahwa Paint telah berubah dan tidak akan memanggil onDraw() tanpa permintaan eksplisit.

Ringkasan

  • invalidate() — mekanisme utama permintaan penggambaran ulang View di Android, bekerja secara asinkron melalui dirty flag
  • postInvalidate() — versi aman untuk thread untuk pemanggilan dari thread latar, menggunakan Handler
  • invalidate(Rect) — penggambaran ulang parsial hanya area yang ditentukan, penting untuk kinerja pada perubahan titik
  • requestLayout() — menjalankan siklus lengkap measure + layout + draw, jauh lebih berat dari invalidate()
  • Choreographer — layanan sistem untuk sinkronisasi dengan Vsync, direkomendasikan untuk animasi dengan invalidate()
  • Hardware Acceleration — percepatan GPU tersedia sejak API 14, mempercepat pemrosesan invalidate() untuk Canvas API
  • GPU Profile Rendering — alat profiling untuk mengukur waktu penggambaran dan mengidentifikasi onDraw() yang lambat

Kami akan mengembangkan aplikasi seluler turnkey

IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.

Diskusikan proyek

Baca juga