마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

안드로이드 게임 제작중 쓰레드 관련 오류

0 추천

안드로이드 게임 프레임워크를 제작 하고 

디펜스 게임을 만들고 있는데 

정상적으로 모든 기능이 작동하다가 홈키 나 백 키를 누르면 

예기치 못한 오류로 종류되었다고 메세지가 뜹니다. 

쓰레드 관련  부분에서 스레드가 제대로 종료되지 않고 프로그램이 죽으면 이러한 에러가 발생한다고 하여서

조인 문장을 첨가하여 바꿔 보았는데도 에러가 잡히지 않아서 조언 부탁드립니다.

 

게임 쓰레드 소스 

package com.mycompany.framework;

import android.graphics.Canvas;
import android.util.Log;
import android.view.SurfaceHolder;

public class GameViewThread extends Thread {
	// 접근을 위한 멤버 변수
		private SurfaceHolder m_surfaceHolder;
		private GameView m_gameview;
		// 스레드 실행 상태 멤버 변수
		private boolean m_run = false;
		 
		public GameViewThread(SurfaceHolder surfaceHolder, GameView gameview) {
			m_surfaceHolder = surfaceHolder;
			m_gameview = gameview;
		}
		 
		public void setRunning(boolean run) {
			m_run = run;
		}
		 
	@Override
	public void run() {
		Canvas _canvas = null;
		while(m_run){
			
			_canvas = null;
			try{
				m_gameview.Update();

				// SurfaceHolder를 통해 Surface에 접근해서 가져옴
				_canvas = m_surfaceHolder.lockCanvas(null);
				synchronized (m_surfaceHolder) {
					m_gameview.onDraw(_canvas); // 그림을 그림
					m_surfaceHolder.unlockCanvasAndPost(_canvas);
				}
			}
			catch(Exception e){ 
				Log.e("EXCEPTION",e.getMessage().toString());
			}
			
		}
	}
}

 

게임 쓰레드를 사용하는 서피스 뷰 부분

package com.mycompany.framework;

import org.Game.GameState;

import android.R.color;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class GameView extends SurfaceView implements SurfaceHolder.Callback{

	private GameViewThread m_thread;
	private IState m_state;
	int Width,Height;

	int x, y;
	String str;
	
	
	
	public void setWindowSize(int w, int h){
		Width = w;
		Height = h;
		
	}

	public GameView(Context context,int w,int h) {
		super(context);        
		setFocusable(true);
    	AppManager.getInstance().setGameView(this);
    	AppManager.getInstance().setResources(getResources());
    	AppManager.getInstance().setSize(getWidth(), getHeight());
  
    	GameState gamestate = GameState.getInstance();
    	ChangeGameState(gamestate);
    	gamestate.setWindowSize(w, h);
    	
        getHolder().addCallback(this);
        m_thread = new GameViewThread(getHolder(),this);
        getHolder().setFixedSize(getWidth(),getHeight());
		
//		ChangeGameState(new 초기 게임 상태());
	}
    @Override
      public void onDraw(Canvas canvas) {
    	canvas.drawColor(Color.BLACK);
	    m_state.Render(canvas);
    }

	public void Update() {
		m_state.Update();
	}

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

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		// 스레드를 실행 상태로 만듭니다.
		m_thread.setRunning(true);
		// 스레드 실행
	    	m_thread.start(); 			
	}
	

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		m_state.onKeyDown(keyCode, event);
		return super.onKeyDown(keyCode, event);
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		m_state.onTouchEvent(event);
		return super.onTouchEvent(event);
	}
	public void ChangeGameState(IState _state){
		if(m_state!=null)
			m_state.Destroy();
		_state.Init();
		m_state = _state;
	}

	
	@Override
	public void surfaceDestroyed(SurfaceHolder arg0) {
		boolean retry = true;
		m_thread.setRunning(false);
		while (retry) {
	        	try {
	        		// 스레드를 중지시킵니다.
	           		m_thread.join();
	            		retry = false;
	        	} catch (InterruptedException e) {
	        		// 스레드가 종료되도록 계속 시도합니다.
	        		e.getStackTrace();
	        	}
	    	}
	}


}

 

platina (120 포인트) 님이 2014년 5월 21일 질문

2개의 답변

0 추천
에러로그도 같이 올려주시면 좋을텐데요...
-쫑- (1,790 포인트) 님이 2014년 5월 21일 답변
0 추천
java 스레드 프로그래밍에 대해 더 공부하시기 바랍니다.

1. m_run 에 접근 하는 모든 코드는 동기화해야 올바르게 동작합니다.

2. interrupt를 사용하면 m_run 같은게 필요없습니다.

3. 스레드 코드에서 모든 Exception을 먹어버리는데, 그러면 안됩니다.  InterruptedException 을 받은 경우 적절하게 종료처리를 하고 스레드를 종료해야 합니다.
익명사용자 님이 2014년 5월 21일 답변
...