invalidate() — bu nədir, yenidənçəkmə mexanizmi və invalidate(Rect)

Müəllif: IT Sectr Dərc olunub: 2026-07-20 Oxuma vaxtı: 7 dəq

invalidate() — Android-də View sinfinin metodudur ki, görünüşü yenidən çəkilmə tələb edən kimi qeyd edir. invalidate() çağırışı görünüşün ekran yeniləmə dövrünün ən yaxın vaxtında yenidən çəkilməsinə səbəb olur və bu, onu xüsusi komponentlərin vizual vəziyyətini yeniləməyin əsas mexanizminə çevirir. Android Developers Documentation (2025) məlumatına görə, invalidate() məlumat dəyişikliklərini ekranda göstərilmə ilə sinxronizasiya etmək üçün 90% xüsusi View-lərdə istifadə olunur. Metod asinxron işləyir — o, sadəcə dirty flagını təyin edir və dərhal idarəetməni qaytarır.

Əsas məqamlar

  • invalidate() — Android-də View-in yenidən çəkilməsi üçün asinxron sorğu, dirty flag mexanizmi ilə işləyir
  • postInvalidate() — fon thread-dən çağırış üçün invalidate() versiyası, thread-təhlükəsizdir
  • invalidate(Rect) — performans optimallaşdırması üçün yalnız göstərilən sahənin qismən yenidən çəkilməsi
  • onDraw() — invalidate()-dən sonra sistem tərəfindən çağırılan metod, iOS-da draw(_:) ilə analoqdur
  • invalidate() vs requestLayout() — invalidate() məzmunu yenidən çəkir, requestLayout() həndəsəni yenidən hesablayır

Android-də invalidate() nədir

invalidate() — android.view.View sinfinin metodudur ki, Android sisteminə görünüşün vizual təsvirinin köhnəldiyini bildirir. Metod çağırıldıqdan sonra sistem görünüşü dirty kimi qeyd edir və onun yenidən çəkilməsini ekran yeniləmə dövrünün ən yaxın vaxtında planlaşdırır (adətən 60 FPS üçün 16 ms).

invalidate() metodu müxtəlif formalar qəbul edir: parametrsiz (tam yenidənçəkmə), Rect parametri ilə (qismən) və ltrb parametrləri ilə (left, top, right, bottom). Bütün versiyalar asinxron işləyir və UI thread-dən çağırıla bilər. Fon thread-lərdən çağırış üçün postInvalidate() mövcuddur.

invalidate() vasitəsilə yenidənçəkmə necə işləyir

Android-də yenidənçəkmə mexanizmi ViewRootImpl üzərində qurulub — View Hierarchy-ni çəkmə üçün Surface ilə birləşdirən daxili komponent. invalidate() çağırıldıqda, ViewRootImpl görünüş sahəsini dirty olaraq qeyd edir və Choreographer — ekran yeniləmə tezliyi ilə çəkməni sinxronizasiya edən sistem xidməti vasitəsilə yenidənçəkmə sorğusu göndərir.

Yenidənçəkmə dövrü

Choreographer Vsync-dən siqnal alır və üçlü keçid işə salır: measure, layout, draw. Lakin invalidate() yalnız draw fazasına təsir edir — measure və layout fazaları requestLayout() çağırılmadıqca icra olunmur. Bu əsas fərqdir: invalidate() requestLayout()-dan daha yüngüldür, çünki həndəsəni yenidən hesablamır.

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() // Yenidənçəkmə sorğusu
    }

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

        // Qrafik xəttinin çəkilməsi
        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 nümunədə, qrafik çəkmək üçün xüsusi View məlumat yenilənəndə invalidate() çağırır. Sistem yalnız bu View-i yenidən çəkir, iyerarxiyanın qalan elementlərinə təsir etmir. onDraw() Path vasitəsilə xətlər çəkmək üçün Canvas alır.

invalidate() vs postInvalidate()

invalidate() və postInvalidate() arasındakı əsas fərq thread təhlükəsizliyindədir. invalidate() yalnız UI thread-dən (main thread) çağırılmalıdır. postInvalidate() istənilən thread-dən çağırıla bilər — Handler vasitəsilə yenidənçəkmə sorğusunu UI thread-ə göndərir.

Xüsusiyyətinvalidate()postInvalidate()
Çağırış thread-iUI thread (main thread)İstənilən thread
MexanizmDirty flag-ın birbaşa yenilənməsiHandler.post() vasitəsilə UI thread-ə
GecikməMinimal, cari dövrdəNövbəti UI thread dövrünə qədər
PerformansYüksəkHandler üzrə kiçik əlavə yük
TövsiyəUI thread üçün həmişə invalidate()Yalnız fon thread-ləri üçün

Praktikada postInvalidate() şəbəkədən məlumat yükləmə, sensor nəticələrinin işlənməsi və ya fon hesablamaları ssenarilərində istifadə olunur. UI thread-dəsinizsə — minimum gecikmə üçün həmişə invalidate() istifadə edin.

kotlin
    // UI thread-dən çağırıldı
view.invalidate()

    // Fon thread-dən çağırıldı
Thread {
    // Ağır hesablamalar
    val result = performHeavyCalculation()
    runOnUiThread {
        updateUi(result)
    }
}.start()

invalidate(Rect) vasitəsilə qismən yenidənçəkmə

invalidate(Rect)invalidate(int l, int t, int r, int b) yenidənçəkmə sahəsini məhdudlaşdırmağa imkan verir. Bu, performans üçün kritikdir: View-in yalnız bir hissəsi yenilənərkən (məsələn, kursor hərəkəti, göstərici dəyişməsi) bütün görünüşü yenidən çəkməyin mənası yoxdur.

Sistem göstərilən dirty düzbucaqlını onDraw()-a canvas.clipBounds vasitəsilə ötürür. onDraw() daxilində clipBounds yoxlanıla bilər və yalnız bu sahə daxilində çəkmə aparıla bilər, baxmayaraq ki, Android Canvas avtomatik olaraq dirty düzbucaqlıdan kənar çəkməni kəsir.

kotlin
    // Qismən yeniləmə: yalnız kursor sahəsi
private val cursorRect = Rect()

fun moveCursorTo(newX: Int, newY: Int) {
    // Köhnə mövqeyi etibarsız et
    invalidate(cursorRect)

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

    // Yeni mövqeyi etibarsız et
    invalidate(cursorRect)
}

Qismən yenidənçəkmə olmadan, hər bir kursor hərəkəti bütün View-i yenidən çəkərdi ki, bu da böyük qrafik üçün bir neçə onluq əvəzinə minlərlə pikselin yenidən çəkilməsi deməkdir. invalidate(Rect) — redaktorlar, çəkmə canvasları və animasiya edilmiş komponentlər üçün məcburi texnikadır.

invalidate() vs requestLayout(): fərq nədir

Ümumi səhvlərdən biri requestLayout()-u invalidate()-in kifayət etdiyi yerdə çağırmaq və əksinə. Fərq əsaslıdır: invalidate() yalnız draw fazasına təsir edir, requestLayout() isə tam measure → layout → draw dövrünü işə salır.

Aspektinvalidate()requestLayout()
Dövr fazalarıYalnız drawmeasure + layout + draw
Nə vaxt istifadə edilməliYalnız çəkmə dəyişir (rəng, mətn, qrafika)Görünüşün ölçüsü və ya mövqeyi dəyişir
PerformansYüngül — yalnız yenidənçəkməAğır — iyerarxiyanın yenidən hesablanması
İyerarxiyaya təsirYalnız cari görünüşValideyn konteynerlərə təsir edə bilər

TextView-də mətni dəyişirsinizsə — invalidate() kifayətdir, çünki görünüşün ölçüsü dəyişmir. Əgər mətn yeni sətirə keçib hündürlüyü artıra bilərsə — requestLayout() lazımdır. Android Lint performans qaydaları vasitəsilə bu cür səhvləri izləməyə kömək edir.

invalidate() performansının optimallaşdırılması

Həddindən artıq invalidate() çağırışları — Android-də xüsusi View-lərin aşağı performansının əsas səbəblərindən biridir. Optimallaşdırma texnikalarına baxaq.

Çağırış tezliyini minimuma endirin

Əgər məlumatlar yüksək tezliklə yenilənirsə (sensorlar, animasiya, video), hər dəyişiklikdə invalidate() çağırmayın. Ekran yeniləmə tezliyi ilə sinxronizasiya üçün ValueAnimator və ya Choreographer.FrameCallback istifadə edin. Bu, invalidate()-in kadr başına bir dəfədən çox çağırılmamasını təmin edir.

Hardware Acceleration istifadə edin

API 14-dən etibarən Android GPU vasitəsilə aparat sürətləndirilməsini dəstəkləyir. Əgər xüsusi View yalnız Canvas API (drawRect, drawCircle, drawPath) istifadə edirsə, sürətləndirmə şəffaf işləyir. DisplayList-uyğun əməliyyatlar üçün invalidate() əhəmiyyətli dərəcədə sürətli işlənir.

kotlin
// Vsync sinxronizasiyası üçün Choreographer istifadə etməklə
private val frameCallback = Choreographer.FrameCallback { frameTimeNanos ->
    updateAnimation(frameTimeNanos)
    invalidate()
    Choreographer.getInstance().postFrameCallback(this)
}

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

Nöqtəvi yeniləmələr üçün invalidate(Rect) istifadə edin, onDraw() daxilindən invalidate() çağırmaqdan çəkinin (sonsuz dövr) və həmişə cihazda GPU Profile Rendering vasitəsilə profil çəkin. Bu, hər kadrın çəkilməsinin dəqiq vaxtını göstərəcək və problemli yerləri müəyyən etməyə kömək edəcək.

Tez-tez verilən suallar

onDraw() daxilindən invalidate() çağırmaq olarmı?

Xeyr, onDraw() daxilində invalidate() çağırışı sonsuz yenidənçəkmə dövrü yaradır: onDraw() invalidate() çağırır, bu da yenidən onDraw()-u işə salır. Bu, CPU-nun 100% yüklənməsinə və kadr itkisinə səbəb olur. ValueAnimator və ya Choreographer vasitəsilə animasiyalardan istifadə edin.

invalidate() postInvalidate()-dən nə ilə fərqlənir?

invalidate() yalnız UI thread-də işləyir və dirty flag-ı dərhal yeniləyir. postInvalidate() Handler vasitəsilə UI thread-ə sorğu göndərir və istənilən fon thread-dən çağırıla bilər. UI thread-dəsinizsə — minimum gecikmə üçün invalidate() istifadə edin.

TextView-də setText() avtomatik invalidate() çağırırmı?

Bəli, TextView daxilində setText() metodu mətn yeniləndikdən sonra invalidate() çağırır. Əgər mətn görünüşün ölçülərini dəyişibsə, əlavə olaraq requestLayout() çağırılır. Standart vidjetlərlə işləyərkən tərtibatçı əl ilə invalidate() çağırmalı deyil.

invalidate() 60 FPS-də performansa necə təsir edir?

Hər invalidate() çağırışı növbəti Vsync-də (hər 16 ms) yenidənçəkmə planlaşdırır. onDraw() 16 ms-dən uzun çəkərsə, kadr itkisi baş verir. onDraw()-u optimallaşdırın — Bitmap-i keşləyin, alokasiyalardan qaçının və GPU çəkməsi üçün Hardware Acceleration istifadə edin.

Paint xüsusiyyətlərini dəyişdikdən sonra invalidate() çağırmaq lazımdırmı?

Bəli, Paint xüsusiyyətlərini (rəng, qalınlıq, üslub) dəyişdikdən sonra invalidate() çağırmaq lazımdır, çünki View Paint obyektlərindəki dəyişiklikləri avtomatik izləmir. Sistem Paint-in dəyişdiyini bilmir və açıq sorğu olmadan onDraw()-u çağırmayacaq.

Nəticə

  • invalidate() — Android-də View-in yenidən çəkilməsi sorğusunun əsas mexanizmi, dirty flag vasitəsilə asinxron işləyir
  • postInvalidate() — fon thread-lərdən çağırış üçün thread-təhlükəsiz versiya, Handler istifadə edir
  • invalidate(Rect) — yalnız göstərilən sahənin qismən yenidən çəkilməsi, nöqtəvi dəyişikliklərdə performans üçün kritikdir
  • requestLayout() — tam measure + layout + draw dövrünü işə salır, invalidate()-dən çox ağırdır
  • Choreographer — Vsync ilə sinxronizasiya üçün sistem xidməti, invalidate() ilə animasiyalar üçün tövsiyə olunur
  • Hardware Acceleration — API 14-dən etibarən GPU sürətləndirməsi mövcuddur, Canvas API üçün invalidate() işlənməsini sürətləndirir
  • GPU Profile Rendering — çəkmə vaxtını ölçmək və yavaş onDraw() aşkar etmək üçün profilləmə aləti

Açar təslim mobil tətbiq hazırlayacağıq

IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.

Layihəni müzakirə et

Həm də oxuyun