본문 바로가기

Programming/android

SurfaceView 사용방법


SurfaceView 사용법은 
1. SurfaceView를 상속 받고, 
2. SurfaceHolder.Callback을 구현하여준 후에, 
3. SurfaceView의 그리기 작업을 핸들링 해줄, Thread를 구현해주면 됩니다.

예제를 보십시다.

package kr.chapter.surfaceview;


import android.content.Context;

import android.graphics.Canvas;

import android.graphics.Color;

import android.util.AttributeSet;

import android.view.SurfaceHolder;

import android.view.SurfaceView;


/**

 * SurfaceView를 이용하기 위해서 android.view.SurfaceView를 상속 받고, 

 * android.view.SurfaceHolder.Callback을 구현 해주어야 한다.

 * SurfaceView는 uiThread를 사용하지 않고, 화면을 표현하기 때문에 좀더 반응성이 좋고, 유연하게 구현이 가능하다. 

 * 또한, SurfaceView는 처리속도가 느린 View에 직접적으로 출력하지 않고, 고속의 메모리 버퍼를 할당받아, 여기에 원하는 처리를 한다음에,

 * 메모리에서 View로 고속 전송을 하기 때문에, 일반적인 View를 사용하는 것보다 처리가 훨씬 빠릅니다.

 */

public class MyGameView extends SurfaceView implements SurfaceHolder.Callback {


    /*

     * SurfaceHolder는 그림을 그리는 등의 작업을 하는 콜백함수이다.

     */

    private SurfaceHolder holder;

    

    /**

     * View를 ui영역과 SurfaceView영역으로 나누어 사용하기 위해,

     * 이 생성자를 사용하도록 합니다.

     * @param context

     * @param attrs

     */

    public MyGameView(Context context, AttributeSet attrs) {

        super(context, attrs);

        holder = getHolder();

        holder.addCallback(this);

        

        mThread = new ViewThread(holder, context);

    }


    /**

     * SurfaceView가 생성될 때 실행되는 부분입니다.

     */

    @Override

    public void surfaceCreated(SurfaceHolder holder) {

        /*

         * 캔버스가 생성될때, 그림을 그려줄 thread를 시작합니다.

         */

        mThread.start();     

    }

    

    /**

     * SurfaceView가 바뀔때 실행되는 부분입니다.

     */

    @Override

    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { }


    /**

     * SurfaceView가 해제될 때 실행되는 부분입니다.

     */

    @Override

    public void surfaceDestroyed(SurfaceHolder holder) {

        // TODO thread stop
  boolean done = true;

        while (done) {

    try {

    mThread.join();        // 스레드가 현재 step을 끝낼 때 까지 대기

    done = false;

} catch (InterruptedException e) {  // 인터럽트 신호가 오면?   

// 그 신호 무시 - 아무것도 않음

   } // while  

    }


    

    /************************

     * Thread 만들기. SurfaceView의 그래픽을 처리하기 위하여 만들어줍니다.

     * SurfaceView는 그래픽 등을 Thread로 처리하는데, Thread는 Thread클래스를 상속받아 만듭니다.

     * Thread 클래스는 run()이라는 콜백 함수를 제공한다.

     ************************/

    

    public class ViewThread extends Thread {

        /*

         * UI와 소통할 SurfaceHolder를 저장할 변수입니다.

         */

        SurfaceHolder mHolder;                  // SurfaceHolder를 저장할 변수

        

        public ViewThread(SurfaceHolder holder, Context context){

            mHolder = holder;

        }

        

        @Override

        public void run() {

            /*

             * canvas를 생성합니다.

             */

            Canvas canvas = null;

            while(true){

                /*

                 * canvas를 잠그고 버퍼를 할당합니다.

                 */

                canvas = mHolder.lockCanvas();  

                try {

                    /*

                     * 동기화를 유지해줍니다.

                     * 다중쓰레드로 꼬이면 안되니까요.

                     */

                    synchronized (mHolder) {    

                        // TODO 실제 그래픽 처리부분을 구현하여 줍니다.

                    }

                    /*

                     * 버퍼의 작업이 끝나면...

                     */

                } finally {                                 

                    if(canvas != null){ 

                        /*

                         * 버퍼의 내용을 view에 전송하여 줍니다.

                         */

                        mHolder.unlockCanvasAndPost(canvas);

                    }

                }

            }

        }

    }

    

    /************************

     * SurfaceView와 Thread의 연결해주어야 합니다.

     * Thread와 SurfaceView를 생성만 하였으므로, 이를 서로 상호 동작할 수 있도록 연결할 고리가 필요하다.

     * SurfaceView에는 여러개의 콜백 함수들이 있는데, 각각 Thread를 조작할 수 있어야 하므로, Thread를 SurfaceView의 전역변수로 선언한다.

     * Thread 클래스는 run()이라는 콜백 함수를 제공한다.

     * 외부에서 Thread를 기동시킬때는 start() 메소드를, 사용하는데 SurfaceView는 View가 생성될때 Thread를 기동시켜야 하므로, SurfaceCreated() 메서드에서 Thread를 기동합니다. 

     ************************/

    public ViewThread mThread;            // SurfaceView를 계속 갱신해 주기 위해 사용할 thread

}


 
실전 앱프로젝트 - 안드로이드 게임 개발편 을 참고하였습니다.
 

'Programming > android' 카테고리의 다른 글

텍스트 마퀴효과  (0) 2011.04.21
전화걸기 인텐트  (0) 2011.04.21
getWindow(),requestFeature(int featureId) 종류  (0) 2011.02.20
안드로이드 키보드의 InputType정리  (3) 2011.02.19
안드로이드 샘플보기  (0) 2011.02.08