Interview QuestionPractical QuestionFollow-up Questions

View Invalidation in the Android View System

skydovesJaewoong Eum (skydoves)||10 min read

View Invalidation in the Android View System

Invalidation refers to the process of marking a View as needing to be redrawn. It is a fundamental mechanism in the Android View system that updates the UI when changes occur. When a View is invalidated, the system knows that it must refresh that particular portion of the screen during the next drawing cycle. By the end of this lesson, you will be able to:

  • Explain what invalidation means and how it triggers a redraw of a View.
  • Describe the difference between invalidate() and postInvalidate().
  • Use partial invalidation to optimize drawing performance.
  • Distinguish between invalidate() and requestLayout() based on what changed.
  • Recognize common mistakes that lead to unnecessary redraws.
  • Understand how hardware acceleration affects the invalidation path.

How Invalidation Works

When you call methods like invalidate() or postInvalidate() on a View, the invalidation process begins. The system flags the View as "dirty," meaning it requires a redraw. During the next frame, the system includes the invalidated View in its drawing pass and updates the visual representation on screen.

For instance, when a View property such as its position, size, or appearance changes, invalidation ensures that the user sees the updated state. The draw pass itself is scheduled on the next Choreographer frame callback, so the actual rendering does not happen synchronously at the point you call invalidate().

The invalidation signal propagates from the view up through its parent hierarchy to the root ViewRootImpl, which coordinates with the system compositor to schedule a full traversal for the next VSYNC frame. This upward propagation ensures that the entire rendering pipeline is aware that at least one view needs redrawing.

Key Methods for Invalidation

There are three primary entry points for requesting a redraw:

  1. invalidate(): Marks the entire View as dirty and schedules it for redraw during the next layout pass. It does not redraw immediately but enqueues the request for the next frame.

  2. invalidate(Rect dirty): An overloaded version that limits the dirty region to a specific rectangle within the View. This optimizes performance by redrawing only the affected area instead of the full view bounds.

  3. postInvalidate(): Posts the invalidation request to the main thread from a background thread. This is the thread safe alternative to invalidate(), which must be called on the UI thread.

  4. postInvalidateOnAnimation(): Similar to postInvalidate() but aligns the invalidation with the next display VSYNC signal. This is preferred for animation driven invalidation because it avoids scheduling redraws between frames.

Using invalidate() to Update a Custom View

Below is an example of a custom View where invalidate() triggers a redraw whenever the state changes:

class CustomView(context: Context) : View(context) {
    private var circleRadius = 50f

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        canvas.drawCircle(
            width / 2f, height / 2f,
            circleRadius,
            Paint().apply { color = Color.RED }
        )
    }

    fun increaseRadius() {
        circleRadius += 20f
        invalidate()
    }
}

This interview continues for subscribers

Subscribe to Dove Letter for full access to exclusive interviews about Android and Kotlin development.

Become a Sponsor