Interview QuestionPractical QuestionFollow-up Questions

SurfaceView and TextureView

skydovesJaewoong Eum (skydoves)||8 min read

SurfaceView and TextureView

Android provides two specialized view classes for rendering content outside the normal view drawing pipeline: SurfaceView and TextureView. Both enable offscreen rendering for use cases like video playback, camera preview, and custom graphics, but they differ in how they integrate with the view hierarchy, which thread performs the rendering, and what transformations they support. By the end of this lesson, you will be able to:

  • Explain how SurfaceView creates a separate rendering surface outside the view hierarchy.
  • Describe how TextureView renders into the view hierarchy using a SurfaceTexture.
  • Identify the threading model differences between the two approaches.
  • Determine when to use each based on performance and transformation requirements.
  • Explain how SurfaceHolder callbacks manage the lifecycle of a SurfaceView.

SurfaceView and the Separate Window

SurfaceView creates a dedicated rendering surface that exists as a separate window behind (or in front of) the application's main window. The Android compositor (SurfaceFlinger) composites this surface independently from the view hierarchy. This separation means SurfaceView rendering does not go through the normal View.draw() pipeline:

class GameSurfaceView(
    context: Context
) : SurfaceView(context), SurfaceHolder.Callback {

    private var renderThread: Thread? = null

    init { holder.addCallback(this) }

    override fun surfaceCreated(holder: SurfaceHolder) {
        renderThread = Thread {
            while (!Thread.interrupted()) {
                val canvas = holder.lockCanvas() ?: continue
                canvas.drawColor(Color.BLACK)
                drawGameFrame(canvas)
                holder.unlockCanvasAndPost(canvas)
            }
        }.also { it.start() }
    }

    override fun surfaceDestroyed(holder: SurfaceHolder) {
        renderThread?.interrupt()
        renderThread?.join()
    }
}

The SurfaceHolder provides lockCanvas() and unlockCanvasAndPost() for drawing. Because the surface is a separate window, rendering can happen on any thread without blocking the main thread. This is the primary advantage of SurfaceView for high frequency rendering scenarios like games, where the render loop runs on a dedicated thread at 60 or 120 frames per second.

The separate window model has a consequence: SurfaceView does not participate in the normal view hierarchy compositing. It cannot be transformed with View.setAlpha(), View.setRotation(), or View.setScaleX(). Animations that move the SurfaceView will move the hole in the main window, but the surface content renders independently. This makes SurfaceView unsuitable for interfaces that need to animate, fade, or clip the rendered content.

TextureView and View Hierarchy Integration

TextureView renders content into a SurfaceTexture, which is then composited as part of the normal view hierarchy. This means TextureView supports all standard view transformations including alpha, rotation, scaling, and clipping:

This interview continues for subscribers

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

Become a Sponsor