안드로이드 게임 프레임워크를 제작 하고
디펜스 게임을 만들고 있는데
정상적으로 모든 기능이 작동하다가 홈키 나 백 키를 누르면
예기치 못한 오류로 종류되었다고 메세지가 뜹니다.
쓰레드 관련 부분에서 스레드가 제대로 종료되지 않고 프로그램이 죽으면 이러한 에러가 발생한다고 하여서
조인 문장을 첨가하여 바꿔 보았는데도 에러가 잡히지 않아서 조언 부탁드립니다.
게임 쓰레드 소스
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();
}
}
}
}