invalidate() — bu nima, qayta chizish mexanizmi va invalidate(Rect)

Muallif: IT Sectr Nashr etilgan: 2026-07-20 O'qish vaqti: 7 daq

invalidate() — Android-dagi View sinfining metodi bo'lib, ko'rinishni qayta chizish talab qiladigan deb belgilaydi. invalidate() chaqiruvi ekran yangilanish siklining eng yaqin vaqtida ko'rinishni qayta chizishga olib keladi va bu uni maxsus komponentlarning vizual holatini yangilashning asosiy mexanizmiga aylantiradi. Android Developers Documentation (2025) ma'lumotlariga ko'ra, invalidate() ma'lumotlar o'zgarishlarini ekranda ko'rsatish bilan sinxronlash uchun 90% maxsus View-larda ishlatiladi. Metod asinxron ishlaydi — u faqat dirty flagini o'rnatadi va darhol boshqaruvni qaytaradi.

Asosiy fikrlar

  • invalidate() — Android-da View-ni qayta chizish uchun asinxron so'rov, dirty flag mexanizmi orqali ishlaydi
  • postInvalidate() — fon thread-dan chaqirish uchun invalidate() versiyasi, thread-xavfsiz
  • invalidate(Rect) — ishlashni optimallashtirish uchun faqat belgilangan hududning qisman qayta chizilishi
  • onDraw() — invalidate() dan keyin tizim tomonidan chaqiriladigan metod, iOS-dagi draw(_:) ga o'xshash
  • invalidate() vs requestLayout() — invalidate() mazmunni qayta chizadi, requestLayout() geometriyani qayta hisoblaydi

Android-da invalidate() nima

invalidate() — android.view.View sinfining metodi bo'lib, Android tizimiga ko'rinishning vizual tasviri eskirganligini bildiradi. Metod chaqirilgandan so'ng, tizim ko'rinishni dirty deb belgilaydi va uni ekran yangilanish siklining eng yaqin vaqtida qayta chizishni rejalashtiradi (odatda 60 FPS uchun 16 ms).

invalidate() metodi turli shakllarni qabul qiladi: parametrsiz (to'liq qayta chizish), Rect parametri bilan (qisman) va ltrb parametrlari bilan (left, top, right, bottom). Barcha versiyalar asinxron ishlaydi va UI thread-dan chaqirilishi mumkin. Fon thread-lardan chaqirish uchun postInvalidate() mavjud.

invalidate() orqali qayta chizish qanday ishlaydi

Android-da qayta chizish mexanizmi ViewRootImpl ga asoslangan — View Hierarchy-ni chizish uchun Surface bilan bog'laydigan ichki komponent. invalidate() chaqirilganda, ViewRootImpl ko'rinish hududini dirty deb belgilaydi va Choreographer — chizishni ekran yangilanish chastotasi bilan sinxronlaydigan tizim xizmati orqali qayta chizish so'rovini yuboradi.

Qayta chizish sikli

Choreographer Vsync dan signal oladi va uchlik o'tishni ishga tushiradi: measure, layout, draw. Biroq invalidate() faqat draw fazasiga ta'sir qiladi — measure va layout fazalari requestLayout() chaqirilmagan bo'lsa, bajarilmaydi. Bu asosiy farq: invalidate() requestLayout() dan yengilroq, chunki geometriyani qayta hisoblamaydi.

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() // Qayta chizish so'rovi
    }

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

        // Grafik chizig'ini chizish
        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)
    }
}

Ushbu misolda, grafik chizish uchun maxsus View ma'lumot yangilanganda invalidate() chaqiradi. Tizim faqat shu View-ni qayta chizadi, iyerarxiyaning qolgan elementlariga ta'sir qilmaydi. onDraw() Path orqali chiziqlar chizish uchun Canvas oladi.

invalidate() vs postInvalidate()

invalidate() va postInvalidate() o'rtasidagi asosiy farq thread xavfsizligidadir. invalidate() faqat UI thread-dan (main thread) chaqirilishi kerak. postInvalidate() istalgan thread-dan chaqirilishi mumkin — Handler orqali qayta chizish so'rovini UI thread-ga yuboradi.

Xususiyatinvalidate()postInvalidate()
Chaqirish thread-iUI thread (asosiy thread)Istalgan thread
MexanizmDirty flag-ni to'g'ridan-to'g'ri yangilashHandler.post() orqali UI thread-ga
KechikishMinimal, joriy sikldaKeyingi UI thread sikligacha
IshlashYuqoriHandlerda kichik qo'shimcha yuk
TavsiyaUI thread uchun har doim invalidate()Faqat fon thread-lari uchun

Amalda, postInvalidate() tarmoqdan ma'lumot yuklash, sensor natijalarini qayta ishlash yoki fon hisoblash stsenariylarida ishlatiladi. UI thread-da bo'lsangiz — minimal kechikish uchun har doim invalidate() dan foydalaning.

kotlin
    // UI thread-dan chaqirildi
view.invalidate()

    // Fon thread-dan chaqirildi
Thread {
    // Og'ir hisoblar
    val result = performHeavyCalculation()
    runOnUiThread {
        updateUi(result)
    }
}.start()

invalidate(Rect) orqali qisman qayta chizish

invalidate(Rect) va invalidate(int l, int t, int r, int b) qayta chizish hududini cheklash imkonini beradi. Bu ishlash uchun juda muhim: View-ning faqat bir qismi yangilanganda (masalan, kursor harakati, indikator o'zgarishi) butun ko'rinishni qayta chizishning ma'nosi yo'q.

Tizim belgilangan dirty to'rtburchakni onDraw() ga canvas.clipBounds orqali uzatadi. onDraw() ichida clipBounds tekshirilishi va faqat shu hudud chegarasida chizish mumkin, garchi Android Canvas avtomatik ravishda dirty to'rtburchakdan tashqaridagi chizishni kesib tashlaydi.

kotlin
    // Qisman yangilash: faqat kursor maydoni
private val cursorRect = Rect()

fun moveCursorTo(newX: Int, newY: Int) {
    // Eski pozitsiyani bekor qilish
    invalidate(cursorRect)

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

    // Yangi pozitsiyani bekor qilish
    invalidate(cursorRect)
}

Qisman qayta chizishsiz, har bir kursor harakati butun View-ni qayta chizadi, bu katta grafik uchun bir necha o'nlab o'rniga minglab piksellarning qayta chizilishi degani. invalidate(Rect) — muharrirlar, chizish canvaslari va animatsiya qilingan komponentlar uchun majburiy texnika.

invalidate() vs requestLayout(): farq nima

Keng tarqalgan xatolardan biri requestLayout() ni invalidate() yetarli bo'lgan joyda chaqirish va aksincha. Farq asosiy: invalidate() faqat draw fazasiga ta'sir qiladi, requestLayout() esa to'liq measure → layout → draw siklini ishga tushiradi.

Aspektinvalidate()requestLayout()
Sikl fazalariFaqat drawmeasure + layout + draw
Qachon ishlatishFaqat chizish o'zgaradi (rang, matn, grafik)Ko'rinishning o'lchami yoki joylashuvi o'zgaradi
IshlashYengil — faqat qayta chizishOg'ir — iyerarxiyani qayta hisoblash
Iyerarxiyaga ta'sirFaqat joriy ko'rinishOta konteynerlarga ta'sir qilishi mumkin

TextView da matnni o'zgartirsangiz — invalidate() yetarli, chunki ko'rinishning o'lchami o'zgarmaydi. Agar matn yangi qatorga o'tib balandlikni oshirishi mumkin bo'lsa — requestLayout() kerak. Android Lint ishlash qoidalari orqali bunday xatolarni kuzatishga yordam beradi.

invalidate() ishlashini optimallashtirish

Haddan tashqari invalidate() chaqiruvlari — Android-da maxsus View-larning past ishlashining asosiy sabablaridan biridir. Optimallashtirish texnikalarini ko'rib chiqaylik.

Chaqiruv chastotasini minimallashtiring

Agar ma'lumotlar yuqori chastota bilan yangilansa (datchiklar, animatsiya, video), har bir o'zgarishda invalidate() chaqirmang. Ekran yangilanish chastotasi bilan sinxronlash uchun ValueAnimator yoki Choreographer.FrameCallback dan foydalaning. Bu invalidate() har bir kadrda bir martadan ko'p chaqirilmasligini kafolatlaydi.

Hardware Acceleration dan foydalaning

API 14 dan boshlab Android GPU orqali apparat tezlashtirishni qo'llab-quvvatlaydi. Agar maxsus View faqat Canvas API (drawRect, drawCircle, drawPath) ishlatsa, tezlashtirish shaffof ishlaydi. DisplayList-ga mos operatsiyalar uchun invalidate() sezilarli darajada tezroq ishlanadi.

kotlin
// Vsync sinxronlash uchun Choreographer dan foydalanish
private val frameCallback = Choreographer.FrameCallback { frameTimeNanos ->
    updateAnimation(frameTimeNanos)
    invalidate()
    Choreographer.getInstance().postFrameCallback(this)
}

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

Nuqtaviy yangilanishlar uchun invalidate(Rect) dan foydalaning, onDraw() ichidan invalidate() chaqirishdan saqlaning (cheksiz sikl) va har doim qurilmada GPU Profile Rendering orqali profil oling. Bu har bir kadrning chizilish vaqtini ko'rsatadi va muammoli joylarni aniqlashga yordam beradi.

Tez-tez so'raladigan savollar

onDraw() ichidan invalidate() chaqirish mumkinmi?

Yo'q, onDraw() ichida invalidate() chaqiruvi cheksiz qayta chizish siklini yaratadi: onDraw() invalidate() chaqiradi, bu yana onDraw() ni ishga tushiradi. Bu CPU ning 100% yuklanishiga va kadr yo'qotilishiga olib keladi. ValueAnimator yoki Choreographer orqali animatsiyalardan foydalaning.

invalidate() postInvalidate() dan qanday farq qiladi?

invalidate() faqat UI thread-da ishlaydi va dirty flag-ni darhol yangilaydi. postInvalidate() Handler orqali UI thread-ga so'rov yuboradi va istalgan fon thread-dan chaqirilishi mumkin. UI thread-da bo'lsangiz — minimal kechikish uchun invalidate() dan foydalaning.

TextView dagi setText() avtomatik invalidate() chaqiradimi?

Ha, TextView ichida setText() matn yangilangandan so'ng invalidate() chaqiradi. Agar matn ko'rinishning o'lchamlarini o'zgartirgan bo'lsa, qo'shimcha ravishda requestLayout() chaqiriladi. Standart vidjetlar bilan ishlaganda dasturchi qo'lda invalidate() chaqirishi shart emas.

invalidate() 60 FPS da ishlashga qanday ta'sir qiladi?

Har bir invalidate() chaqiruvi keyingi Vsync da (har 16 ms) qayta chizishni rejalashtiradi. Agar onDraw() 16 ms dan uzoq davom etsa, kadr yo'qotilishi sodir bo'ladi. onDraw() ni optimallashtiring — Bitmap ni keshlang, ajratmalardan qoching va GPU chizish uchun Hardware Acceleration dan foydalaning.

Paint xususiyatlarini o'zgartirgandan keyin invalidate() chaqirish kerakmi?

Ha, Paint xususiyatlarini (rang, qalinlik, uslub) o'zgartirgandan keyin invalidate() chaqirish kerak, chunki View Paint ob'ektlaridagi o'zgarishlarni avtomatik kuzatmaydi. Tizim Paint o'zgarganini bilmaydi va aniq so'rovsiz onDraw() ni chaqirmaydi.

Xulosa

  • invalidate() — Android-da View-ni qayta chizish so'rovining asosiy mexanizmi, dirty flag orqali asinxron ishlaydi
  • postInvalidate() — fon thread-lardan chaqirish uchun thread-xavfsiz versiya, Handler dan foydalanadi
  • invalidate(Rect) — faqat belgilangan hududning qisman qayta chizilishi, nuqtaviy o'zgarishlarda ishlash uchun muhim
  • requestLayout() — to'liq measure + layout + draw siklini ishga tushiradi, invalidate() dan ancha og'ir
  • Choreographer — Vsync bilan sinxronlash uchun tizim xizmati, invalidate() bilan animatsiyalar uchun tavsiya etiladi
  • Hardware Acceleration — API 14 dan boshlab GPU tezlashtirish mavjud, Canvas API uchun invalidate() ishlovini tezlashtiradi
  • GPU Profile Rendering — chizish vaqtini o'lchash va sekin onDraw() larni aniqlash uchun profillash vositasi

Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz

IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.

Loyihani muhokama qilish

Shuningdek o'qing