SurfaceView 기본 개념

Android 2011. 4. 11. 15:49
안드로이드에서 기본적으로 제공되는 컴포넌트들(ImageView, TextView, Layout 등)은

빠른 화면 갱신을 요하는 게임이나 실시간 그래프 등의 작업에서는 깜빡이는 현상이 일어난다.

현재 화면에 나타나 있는 UI에서 직접 그리는 작업을 하는 동안 사용자 입력을 받을 수 없는 상태이며

어떤 동작 후 화면에 뿌려지기까지 시간이 길어진다면 긴 대기상태에 대한 종료를 묻는 팝업이 뜨게 된다.(ANR)

그리기를 위해 안드로이드에서는 더블버퍼링 방식의 SurfaceView를 제공하고 있다.

더블버퍼링이란 화면에 보이지 않는 영역에서 어떤 공간에(실제로는 메모리 상에) 그림을 그린 후

UI에 붙이는 방식인데, 앞서 깜빡이는 현상의 경우 싱글버퍼링이기 때문이다.

싱글버퍼링은 메인UI에서 그림을 그리는 동작을 수행하기 때문에 그림을 그리는 동안에는

결국 메인 스레드 작업이기 때문에 사용자와 인터랙션을 할 수 없다.


이런 SurfaceView에는 꼭 알아야할 몇 가지 요소가 있다.

먼저 SurfaceView는 View를 상속받았기 때문에 setContentView 메서드를 통해 붙여넣기가 가능하다.

ex) setContentView(new MySurfaceView(this));

SurfaceView는 현재 메인 스레드가 아닌 보이지 않는 영역에서 그림을 미리 그린다고 했다. 

그 공간을 Surface라 하며 그 공간에 그림이 그려질 영역을 설정하는 부분은 Canvas를 통해 한다.

Canvas는 그림이 위치할 도화지 혹은 Layout의 개념으로 봐도 무방했다.(개인적인 생각)

현재는 배경 색이나 정렬 등을 수행할 수는 있으나 원하는 작업을 모두 할 수는 없는 도화지 상태이다.

Canvas가 올려질 영역은 Bitmap이다.

Bitmap에 올라간 Canvas는 SurfaceHolder를 통해서 Surface에 붙여진다.

결국 SurfaceHolder가 없으면 메모리상에서 그리기만 수행하고 보여지진 않은 꼴이 되며 보여줄 수가 없다. 

SurfaceHolder의 경우 SurfaceView 생성자 직후 호출되는 public void surfaceCreated(SurfaceHolder holder) 메서드에서

필드로 받아 사용하는 방법이 있다.

SurfaceHolder를 통해 SurfaceView에 붙이는 과정은 다음과 같다. (편의상 Paint와 Bitmap의 초기화 과정은 생략)

1. 그릴 Canvas를 생성한 후 그 Canvas를 잠근다.

mCanvas = mHolder.lockCanvas();



SurfaceHolder를 통해 잠긴 Canvas를 반환받아 다른 thread 등에서의 접근을 막는다.

2. Canvas에 Bitmap을 추가하거나 Canvas의 색상 정보 등을 입력한다.

mCanvas = drawColor(0xFFECECEC);
mCanvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint); 


3. 잠긴 Canvas를 푼다.

mHolder.unlockCanvasAndPost(mCanvas);


3 과정이 빠진 경우에 해당 Canvas를 다른 곳에서 접근하려 하면

해당 Canvas를 인자로 넘긴 곳에 잘못된 인자 정보라는 에러가 뜨게 된다.

또한 3 과정에서의 메서드 이름에서 알 수 있듯이

실제로 Canvas의 락이 해제되고 mHolder를 통해 Canvas가 보여지는 과정이다.
 

'Android' 카테고리의 다른 글

Android 메모리 릭 피하기 번역  (0) 2012.06.12
Android code snippets  (0) 2011.05.11
CalledFromWrongThreadException  (0) 2011.05.04
AbsoluteLayout has been deprecated.  (0) 2011.02.08
안드로이드 기본 셋팅  (0) 2011.01.10
Posted by 독뽀
,