invalidate() — ano ito, mekanismo ng muling pagguhit at invalidate(Rect)

May-akda: IT Sectr Nai-publish: 2026-07-20 Oras ng pagbabasa: 7 min

invalidate() — ay isang pamamaraan ng klase ng View sa Android na nagmamarka ng view bilang nangangailangan ng muling pagguhit. Ang pagtawag sa invalidate() ay humahantong sa muling pagguhit ng view sa pinakamalapit na cycle ng pag-update ng screen, na ginagawa itong pangunahing mekanismo para sa pag-update ng visual na estado ng mga custom na bahagi. Ayon sa Android Developers Documentation (2025), ang invalidate() ay ginagamit sa 90% ng mga custom na View para i-synchronize ang mga pagbabago sa data sa pagpapakita sa screen. Ang pamamaraan ay gumagana nang asynchronous — ito ay nagtatakda lamang ng dirty flag at agad na nagbabalik ng kontrol.

Mga Pangunahing Punto

  • invalidate() — asynchronous na kahilingan para sa muling pagguhit ng View sa Android, gumagana sa pamamagitan ng dirty flag mechanism
  • postInvalidate() — bersyon ng invalidate() para sa pagtawag mula sa background thread, ligtas sa thread
  • invalidate(Rect) — bahagyang muling pagguhit lamang ng tinukoy na lugar para sa pag-optimize ng pagganap
  • onDraw() — pamamaraan na tinatawag ng sistema pagkatapos ng invalidate(), katulad ng draw(_:) sa iOS
  • invalidate() vs requestLayout() — invalidate() ay muling gumuhit ng nilalaman, requestLayout() ay muling kumukwenta ng geometry

Ano ang invalidate() sa Android

invalidate() — ay isang pamamaraan ng klase ng android.view.View na nagpapaalam sa Android system na ang visual na representasyon ng view ay luma na. Pagkatapos ng pagtawag sa pamamaraan, minamarkahan ng sistema ang view bilang dirty at nag-iiskedyul ng muling pagguhit nito sa pinakamalapit na cycle ng pag-update ng screen (karaniwang 16 ms para sa 60 FPS).

Ang pamamaraang invalidate() ay tumatanggap ng iba't ibang anyo: walang parameter (buong muling pagguhit), may parameter na Rect (bahagyang) at may mga parameter na ltrb (left, top, right, bottom). Lahat ng bersyon ay gumagana nang asynchronous at maaaring tawagin mula sa UI thread. Para sa pagtawag mula sa mga background thread ay mayroong postInvalidate().

Paano gumagana ang muling pagguhit sa pamamagitan ng invalidate()

Ang mekanismo ng muling pagguhit sa Android ay batay sa ViewRootImpl — isang panloob na bahagi na nag-uugnay ng View Hierarchy sa Surface para sa pagguhit. Kapag tinawag ang invalidate(), minamarkahan ng ViewRootImpl ang lugar ng view bilang dirty at nagpapadala ng kahilingan sa muling pagguhit sa pamamagitan ng Choreographer — isang serbisyo ng sistema na nag-si-synchronize ng pagguhit sa dalas ng pag-update ng screen.

Cycle ng muling pagguhit

Ang Choreographer ay tumatanggap ng signal mula sa Vsync at naglulunsad ng triple pass: measure, layout, draw. Gayunpaman, ang invalidate() ay nakakaapekto lamang sa draw phase — ang measure at layout phase ay hindi isinasagawa maliban kung tinawag ang requestLayout(). Ito ang pangunahing pagkakaiba: ang invalidate() ay mas magaan kaysa sa requestLayout() dahil hindi nito kinukwenta muli ang geometry.

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() // Kahilingan sa muling pagguhit
    }

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

        // Pagguhit ng linya ng graph
        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)
    }
}

Sa halimbawang ito, ang isang custom na View para sa pagguhit ng graph ay tumatawag ng invalidate() kapag nag-a-update ng data. Ang sistema ay muling gumuhit lamang ng View na ito, nang hindi naaapektuhan ang iba pang mga elemento ng hierarchy. onDraw() ay tumatanggap ng Canvas para sa pagguhit ng mga linya sa pamamagitan ng Path.

invalidate() vs postInvalidate()

Ang pangunahing pagkakaiba sa pagitan ng invalidate() at postInvalidate() ay ang kaligtasan sa thread. invalidate() ay dapat lamang tawagin mula sa UI thread (pangunahing thread). postInvalidate() ay maaaring tawagin mula sa anumang thread — sa pamamagitan ng Handler nagpapadala ito ng kahilingan sa muling pagguhit sa UI thread.

Katangianinvalidate()postInvalidate()
Thread ng pagtawagUI thread (pangunahing thread)Anumang thread
MekanismoDirektang pag-update ng dirty flagSa pamamagitan ng Handler.post() sa UI thread
LatencyMinimal, sa kasalukuyang cycleHanggang sa susunod na cycle ng UI thread
PagganapMataasMaliit na overhead sa Handler
RekomendasyonPara sa UI thread palaging invalidate()Para lamang sa mga background thread

Sa praktika, ang postInvalidate() ay ginagamit sa mga senaryo ng pag-load ng data mula sa network, pagproseso ng mga resulta ng sensor o mga background computation. Kung ikaw ay nasa UI thread — palaging gamitin ang invalidate() para sa minimal na latency.

kotlin
    // Tinawag mula sa UI thread
view.invalidate()

    // Tinawag mula sa background thread
Thread {
    // Mabibigat na kalkulasyon
    val result = performHeavyCalculation()
    runOnUiThread {
        updateUi(result)
    }
}.start()

Bahagyang muling pagguhit sa pamamagitan ng invalidate(Rect)

invalidate(Rect) at invalidate(int l, int t, int r, int b) ay nagbibigay-daan sa paglilimita sa lugar ng muling pagguhit. Ito ay kritikal para sa pagganap: kapag nag-a-update lamang ng bahagi ng View (halimbawa, paggalaw ng cursor, pagbabago ng indicator) walang saysay na muling iguhit ang buong view.

Ipinapasa ng sistema ang tinukoy na dirty rectangle sa onDraw() sa pamamagitan ng canvas.clipBounds. Sa loob ng onDraw() ay maaaring suriin ang clipBounds at gumuhit lamang sa loob ng lugar na ito, bagaman ang Android Canvas ay awtomatikong pinuputol ang pagguhit sa labas ng dirty rectangle.

kotlin
    // Bahagyang pag-update: lugar ng cursor lamang
private val cursorRect = Rect()

fun moveCursorTo(newX: Int, newY: Int) {
    // Invalidate lumang posisyon
    invalidate(cursorRect)

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

    // Invalidate bagong posisyon
    invalidate(cursorRect)
}

Kung walang bahagyang muling pagguhit, bawat paggalaw ng cursor ay muling iguguhit ang buong View, na para sa isang malaking graph ay nangangahulugan ng muling pagguhit ng libu-libong pixel sa halip na ilang dosena. invalidate(Rect) — isang sapilitang pamamaraan para sa mga editor, canvas ng pagguhit at mga animated na bahagi.

invalidate() vs requestLayout(): ano ang pagkakaiba

Ang isa sa mga karaniwang pagkakamali ay ang pagtawag ng requestLayout() kung saan sapat na ang invalidate(), at kabaliktaran. Ang pagkakaiba ay pundamental: invalidate() ay nakakaapekto lamang sa draw phase, habang ang requestLayout() ay naglulunsad ng buong measure → layout → draw cycle.

Aspektoinvalidate()requestLayout()
Mga phase ng cycleDraw lamangmeasure + layout + draw
Kailan gagamitinPagbabago lamang ng pagguhit (kulay, teksto, graph)Pagbabago ng laki o posisyon ng view
PagganapMagaan — muling pagguhit lamangMabigat — muling pagkukwenta ng hierarchy
Epekto sa hierarchyKasalukuyang view lamangMaaaring makaapekto sa mga container na magulang

Kung magbabago ng teksto sa TextView — sapat na ang invalidate(), dahil hindi nagbabago ang laki ng view. Kung ang teksto ay maaaring lumipat sa bagong linya at dagdagan ang taas — kailangan ang requestLayout(). Android Lint ay tumutulong subaybayan ang mga ganitong pagkakamali sa pamamagitan ng mga patakaran sa pagganap.

Pag-optimize ng pagganap ng invalidate()

Ang labis na mga tawag sa invalidate() — isa sa mga pangunahing dahilan ng mababang pagganap ng mga custom na View sa Android. Tingnan natin ang mga pamamaraan ng pag-optimize.

I-minimize ang dalas ng pagtawag

Kung ang data ay nag-a-update na may mataas na dalas (mga sensor, animation, video), huwag tawagin ang invalidate() sa bawat pagbabago. Gamitin ang ValueAnimator o Choreographer.FrameCallback para sa pag-sync sa dalas ng pag-update ng screen. Tinitiyak nito na ang invalidate() ay tinatawag nang hindi hihigit sa isang beses bawat frame.

Gamitin ang Hardware Acceleration

Mula sa API 14, sinusuportahan ng Android ang hardware acceleration sa pamamagitan ng GPU. Kung ang iyong custom na View ay gumagamit lamang ng Canvas API (drawRect, drawCircle, drawPath), ang acceleration ay gumagana nang transparent. Para sa mga operasyong compatible sa DisplayList, ang invalidate() ay pinoproseso nang mas mabilis.

kotlin
// Paggamit ng Choreographer para sa Vsync synchronization
private val frameCallback = Choreographer.FrameCallback { frameTimeNanos ->
    updateAnimation(frameTimeNanos)
    invalidate()
    Choreographer.getInstance().postFrameCallback(this)
}

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

Gamitin ang invalidate(Rect) para sa mga point update, iwasan ang pagtawag ng invalidate() mula sa onDraw() (walang katapusang loop), at palaging mag-profile sa pamamagitan ng GPU Profile Rendering sa device. Ipapakita nito ang eksaktong oras ng pagguhit ng bawat frame at makakatulong na matukoy ang mga problematikong lugar.

Mga Madalas Itanong

Maaari bang tawagin ang invalidate() mula sa onDraw()?

Hindi, ang pagtawag sa invalidate() sa loob ng onDraw() ay lumikha ng walang katapusang loop ng muling pagguhit: onDraw() ay tumatawag ng invalidate(), na muling nagpapatakbo ng onDraw(). Ito ay humahantong sa 100% na pag-load ng CPU at pagbaba ng frame. Gamitin ang mga animation sa pamamagitan ng ValueAnimator o Choreographer.

Paano naiiba ang invalidate() sa postInvalidate()?

invalidate() ay gumagana lamang sa UI thread at nag-a-update ng dirty flag agad. postInvalidate() ay nagpapadala ng kahilingan sa pamamagitan ng Handler sa UI thread at maaaring tawagin mula sa anumang background thread. Kung ikaw ay nasa UI thread — gamitin ang invalidate() para sa minimal na latency.

Ang setText() ba sa TextView ay awtomatikong tumatawag ng invalidate()?

Oo, sa loob ng TextView ang pamamaraang setText() ay tumatawag ng invalidate() pagkatapos i-update ang teksto. Kung binago ng teksto ang mga dimensyon ng view, dagdag na tinatawag ang requestLayout(). Ang developer ay hindi kailangang manu-manong tumawag ng invalidate() kapag nagtatrabaho sa mga standard na widget.

Paano naaapektuhan ng invalidate() ang pagganap sa 60 FPS?

Bawat pagtawag sa invalidate() ay nag-iiskedyul ng muling pagguhit sa susunod na Vsync (bawat 16 ms). Kung ang onDraw() ay tumatagal ng higit sa 16 ms, nangyayari ang pagbaba ng frame. I-optimize ang onDraw() — i-cache ang Bitmap, iwasan ang mga alokasyon, at gamitin ang Hardware Acceleration para sa GPU drawing.

Kailangan bang tumawag ng invalidate() pagkatapos baguhin ang mga katangian ng Paint?

Oo, pagkatapos baguhin ang mga katangian ng Paint (kulay, kapal, estilo) kailangang tumawag ng invalidate(), dahil hindi awtomatikong sinusubaybayan ng View ang mga pagbabago sa mga object ng Paint. Hindi alam ng sistema na nagbago ang Paint at hindi tatawag ng onDraw() nang walang malinaw na kahilingan.

Buod

  • invalidate() — pangunahing mekanismo ng kahilingan para sa muling pagguhit ng View sa Android, gumagana nang asynchronous sa pamamagitan ng dirty flag
  • postInvalidate() — bersyon na ligtas sa thread para sa pagtawag mula sa mga background thread, gumagamit ng Handler
  • invalidate(Rect) — bahagyang muling pagguhit lamang ng tinukoy na lugar, kritikal para sa pagganap sa mga point na pagbabago
  • requestLayout() — naglulunsad ng buong measure + layout + draw cycle, mas mabigat kaysa sa invalidate()
  • Choreographer — serbisyo ng sistema para sa pag-sync sa Vsync, inirerekomenda para sa mga animation na may invalidate()
  • Hardware Acceleration — GPU acceleration na available mula sa API 14, nagpapabilis ng pagproseso ng invalidate() para sa Canvas API
  • GPU Profile Rendering — tool sa profiling para sa pagsukat ng oras ng pagguhit at pagtukoy ng mabagal na onDraw()

Gagawa kami ng mobile application na turnkey

Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.

Pag-usapan ang proyekto

Basahin din