면접 질문 목록으로 가기
면접 질문실전 질문꼬리 질문

SurfaceView와 TextureView

skydovesJaewoong Eum (skydoves)||7분 소요

SurfaceView와 TextureView

안드로이드는 일반적인 뷰 드로잉 파이프라인 외부에서 콘텐츠를 렌더링하기 위한 두 가지 특수한 뷰 클래스를 제공합니다. 바로 SurfaceViewTextureView입니다. 두 클래스 모두 비디오 재생, 카메라 프리뷰, 커스텀 그래픽 등 오프스크린 렌더링(offscreen rendering) 사용 사례에 활용되지만, 뷰 계층 구조와의 통합 방식, 렌더링을 수행하는 스레드, 지원하는 변환(transformation) 종류에서 뚜렷한 차이가 있습니다. 면접에서는 두 클래스의 내부 동작 원리와 적절한 사용 시점을 정확히 구분할 수 있는지가 핵심이므로, 단순 암기가 아닌 근본적인 이해가 필요합니다.

이번 면접 질문을 통하여 아래 내용들을 학습하실 수 있습니다.

  • SurfaceView가 뷰 계층 구조 외부에 별도의 렌더링 서피스(surface)를 생성하는 원리를 설명할 수 있습니다.
  • TextureViewSurfaceTexture를 활용하여 뷰 계층 구조 내부에서 렌더링하는 방식을 이해할 수 있습니다.
  • 두 접근 방식 간의 스레딩 모델 차이를 식별할 수 있습니다.
  • 성능 요구 사항과 변환 지원 여부에 따라 적절한 클래스를 선택하는 기준을 판단할 수 있습니다.
  • SurfaceHolder 콜백이 SurfaceView의 생명주기를 관리하는 과정을 설명할 수 있습니다.

SurfaceView와 별도 윈도우 모델

SurfaceView는 애플리케이션 메인 윈도우 뒤쪽(또는 앞쪽)에 별도의 윈도우로 존재하는 전용 렌더링 서피스를 생성합니다. 안드로이드 컴포지터(compositor)인 SurfaceFlinger가 이 서피스를 뷰 계층 구조와 독립적으로 합성(compositing)하기 때문에, SurfaceView의 렌더링은 일반적인 View.draw() 파이프라인을 거치지 않습니다. 쉽게 말해, 메인 윈도우에 "구멍"을 뚫어 놓고 그 뒤에서 별도 서피스가 독립적으로 그려지는 구조라고 이해하시면 됩니다.

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()
    }
}

SurfaceHolderlockCanvas()unlockCanvasAndPost() 메서드를 통해 드로잉 인터페이스를 제공합니다. 서피스가 별도 윈도우로 존재하므로 메인 스레드를 차단하지 않고 어떤 스레드에서든 렌더링할 수 있으며, 이것이 바로 SurfaceView가 고빈도 렌더링 시나리오에서 강력한 이유입니다. 게임처럼 전용 렌더 스레드에서 60fps 또는 120fps로 렌더 루프를 실행해야 하는 경우에 특히 적합합니다.

하지만 별도 윈도우 모델에는 중요한 제약 사항이 따릅니다. SurfaceView는 일반적인 뷰 계층 구조 합성에 참여하지 않기 때문에, View.setAlpha(), View.setRotation(), View.setScaleX() 같은 변환을 적용할 수 없습니다. SurfaceView를 이동시키는 애니메이션은 메인 윈도우의 "구멍"만 이동시킬 뿐, 서피스 콘텐츠 자체는 독립적으로 렌더링됩니다. 따라서 렌더링된 콘텐츠에 애니메이션, 페이드, 클리핑(clipping)을 적용해야 하는 인터페이스에는 SurfaceView가 적합하지 않습니다.

이 면접 질문은 구독자 전용입니다

Dove Letter를 구독하시면 안드로이드, 코틀린 개발 관련 독점 면접 질문의 전체 내용을 볼 수 있습니다.

구독하기
면접 질문 목록으로 가기