관리 메뉴

moozi

그래픽 2D 2 - SurfaceView 활용 1 본문

안드로이드개발강좌

그래픽 2D 2 - SurfaceView 활용 1

moozi 2010. 3. 6. 23:17


이번 강좌에서는 SurfaceView를 활용하는 방법을 알아보겠습니다.

지난 강좌 '그래픽 2D 1 - 안드로이드 아이콘 띄우기, 커스텀뷰 활용' 과 실행결과는 같으나 SurfaceView를 사용하여 구현된 점이 다른점입니다

SurfaceView View클래스의 서브클래스로서, 게임이나 카메라 프리뷰와 같은 작업을 위해서 UI Thread 와 별개로 (독립적으로) 그래픽을 그릴 수 있도록 해줍니다.  SurfaceView를 참조하는 Secondary Thread는 자신만의 페이스(pace)로 자신만의 Canvas에 그릴수 있습니다. 그리고 SurfaceView 를 통해 실제 그래픽을 그리기 위해서는 SurfaceHolder가 필요합니다.

단계적으로 코드를 작성하며 살펴보겠습니다.


1. 다음과 같이 프로젝트를 생성합니다.



2. src -> my.MyGraphics2D02 -> MyGraphics2D02.java 파일을 다음과 같이 편집합니다.

package my.MyGraphics2D02;

import android.app.Activity;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.Window;

public class MyGraphics2D02 extends Activity {
 @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(new CustomView(this));
    }
 
    class CustomView extends SurfaceView implements SurfaceHolder.Callback {
       
    }
 
    class CustomViewThread extends Thread {

    }
}

위의 코드는 완성된 코드는 아니며, 코드전체의 윤곽을 보여주는 클래스들을 먼저 작성한 것입니다.

setContentView(new CustomView(this)); 에서 CustomView클래스를 사용해서 화면을 구성합니다.

class CustomView extends SurfaceView implements SurfaceHolder.Callback  에서
CustomView클래스는 SurfaceView 클래스와 SurfaceHolder.Callback  인터페이스를 상속받아서 작성합니다. SurfaceView를 이용해서 그림을 그리기 위해서는 SurfaceHolder가 필요하며, SurfaceHolder.Callback 인터페이스는 SunfraceHolder 인터페이스의 Nested Interface 입니다.

class CustomViewThread extends Thread  에서
CustomViewThread 는 Thread 클래스를 상속 받아 작성합니다. CustomViewThread 는 SurfaceView와 연계되어 독립적으로 그림을 그리는 작업을 수행하게될 Thread입니다.


3. CustomView 클래스 내부에 다음과 같이 편집합니다.

class CustomView extends SurfaceView implements SurfaceHolder.Callback {
       
        public CustomView(Context context) {
            super(context);
            getHolder().addCallback(this);
 
        }
 
        @Override
        public void onDraw(Canvas canvas) {
         Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.icon);
            canvas.drawColor(Color.parseColor("#dedede"));
            canvas.drawBitmap(bm, 70, 70, null);
        }
 
        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            
        }
 
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            
        }
 
        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            
        }
    }

위의 코드 역시 아직 완성된 코드는 아니며, CustomView 클래스를 구성하는 메서드들을 먼저 작성한 것입니다.

getHolder().addCallback(this); 는  Callback을 위해서 SurfaceHolder CustomView를 추가합니다.

onDraw 는 지난 강좌에서 처럼 이미지파일로 비트맵을 만들고, Canvas에 그리는 역할을 합니다.

SurfaceHolder.Callback  인터페이스는 SurfaceHolder 인터페이스의 Nested Interface인데surfaceChanged, surfaceCreated, surfaceDestroyed 메서드를 오버라이딩 해야합니다.
- surfaceChanged 는 surface 에 구조적인 변화 ( format, size 등 ) 가 있을 때 호출됩니다.
- surfaceCreated 는 surface가 처음 생성될 때 호출됩니다.
- surfaceDestroyed 는 surface가 소멸(Destroyed)될 때 호출됩니다.


4. 이번에는 CustomViewThread  클래스 내부를 다음과 같이 편집합니다.

class CustomViewThread extends Thread {
        private SurfaceHolder surfaceholder;
        private CustomView customview;
        private boolean running = false;
 
        public CustomViewThread(SurfaceHolder surfaceHolder, CustomView CustomView) {
            surfaceholder = surfaceHolder;
            customview = CustomView;
        }
 
        public void setRunning(boolean run) {
            running = run;
        }
 
        @Override
        public void run() {
       
        }
           
}

역시 이번에도 완성된 코드가 아니라 CustomViewThread 클래스를 구성하는 주요 멤버들의 개요를 먼저 작성하였습니다.

running 은 Thread의 running 상태를 표시하는데 사용되는 멤버변수입니다.

CustomViewThread 생성자에서는 멤버변수 surfaceholder, customview 를 초기화 합니다.

setRunning 은 priavate 멤버변수 running 에 값을 저장하는 역할을 합니다.

run 은 Thread 가 수행할 작업을 구현하는 메서드입니다.


다음 강좌에서는 나머지 부분을 완성해 보도록 하겠습니다.


다음강좌 [ 안드로이드 개발 2.0 ] 그래픽 2D 3 - SurfaceView 활용 2 로 이어집니다.


4 Comments
  • 프로필사진 solkit 2010.03.11 05:33 안녕하세요? 개인적인 일로 일주일 정도 접속을 못했는데. 벌써 그래픽에 대한 강좌 4개가 진행 됐네요.

    보다 보니까 모르겠는게 있어서요.

    CustomView 클래스에서 오버라이드 한 메소드가 여러개 있잖아요.
    surfaceChanged,created,destroyed 는 References 보니까 implements 한 SurfaceHolder.Callback 에 있는 메소드 들어 있고 onDraw는 view 클래스에 들어 있네요.

    자바에 대한 기본 지식이 부족해서 그런지... 이런 질문을 한번 드려 보는데요.

    내가 원하는 기능을 구현하기 위해서 이런 메소드들을 쉽게 찾아서 구현 할 수 있으려면 어떻게 해야 되죠?

    Reference를 뒤져보면서 찾아보나요? 아니면 다른 쉽게 찾을 수 있는 방법이 있나요?
    (혹시 질문이 답답하더라도 경험이 많지 않은 프로그래머의 유치한 질문이라고 너그러이 생각해 주시구 조언좀 부탁드립니다.)

    항상 강좌 감사히 잘 보고 있습니다.
    감사합니다.
  • 프로필사진 moozi 2010.03.11 20:57 신고 클래스 내부의 메서드를 찾아보는 것은 역시 Reference를 보시는것이 좋습니다.

    불편하더라도 Reference를 자주 접하는것이 나중에 개발할 때도 도움이 많이 되는것 같습니다.

    다른방법으로는

    이클립스에서 클래스를 만든 후 마우스 오른쪽 버튼을 누르면 나오는 메뉴에서 source -> Override/ Implements Method 를 누르면 오버라이드 해야할 메서드를 자동으로 코딩해 줍니다.

    이것도 한번 써보세요

    ^^
  • 프로필사진 할라당 2010.05.25 11:56 질문있습니다.
    SurfaceHolder.Callback 인터페이스를 사용할 때는
    쓰레드를 사용해야 한는 건가요??
  • 프로필사진 moozi 2010.05.25 22:14 신고 SurfaceHolder.Callback 인터페이스는 SurfaceHolder 인터페이스의 Nested Interface인데, surfaceChanged, surfaceCreated, surfaceDestroyed 메서드를 이용하기 위해서 필요합니다.

    SurfaceView 를 사용하는 이유는 main 쓰레드와는 별개의 쓰레드를 사용해서 그림을 그리기 위해서 입니다.

    그런데, surfaceCreated 메서드와 surfaceDestroyed 메서드에서 이 쓰레드를 사용하므로 말씀하신대로 SurfaceHolder.Callback 인터페이스를 사용할 때는
    쓰레드를 사용해야 한다고 해도 맞는 이야기가 되는것 같아요...

    ^^
댓글쓰기 폼