안드로이드 개발 질문/답변
(글 수 45,052)
현재 surfaceview를 이용한 게임 제작 중 입니다.
app 구동 시 이미지 로딩을 위한 스레드를 하나 생성하고
로딩 중엔 프로그레스 다이얼 로그를 띄워 로딩중을 알리도록 하였습니다.
위 스레드는 이미지와 사운드 리소스 로딩만을 해주도록 만들어주었고(anr 팝업 문제가 생겨서 게임 스레드쪽에 있던걸
따로 스레드를 만들어주었습니다.) 리소스 로딩이 완료되면 게임 스레드(surfaceview쪽)를 start하도록 구현하였습니다.
그런데 어플 구동 테스트를 해보니 간혹가다가 프로그레스 다이얼로그가 보여진 후 게임으로 넘어가질 않는 현상이
발생합니다.
- 현상 1 : 프로그레스 다이얼로그가 뜬 상태로 진행 안됨
- 현상 2 : app 시작 시 프로그레스 다이얼로그도 안뜨고 그냥 까만 화면으로 정지
로그상에 특별한 에러 메세지도 없고 자주도 아니고 가끔가다가 발생을 하고 있습니다.
lifecycle 관련 메서드쪽에 로그를 찍어보니 정상적일땐
12-18 12:46:16.765: DEBUG/[debug](14926): _onCreate
12-18 12:46:16.780: DEBUG/[debug](14926): _GameView
12-18 12:46:16.952: DEBUG/[debug](14926): _onStart
12-18 12:46:16.952: DEBUG/[debug](14926): _onResume
12-18 12:46:17.194: DEBUG/[debug](14926): _surfaceCreated
12-18 12:46:17.194: DEBUG/[debug](14926): _surfaceChanged
12-18 12:46:19.812: DEBUG/[debug](14926): _img_End // 이미지 로드 완료
12-18 12:46:19.819: DEBUG/[debug](14926): _onWindowFocusChanged
12-18 12:46:21.046: DEBUG/[debug](14926): _sound_End // 사운드 로드 완료
12-18 12:46:21.046: DEBUG/[debug](14926): _Handler
12-18 12:46:21.054: DEBUG/[debug](14926): _run
위와같이 타고 들어오고
문제가 발생할땐
_onCreate
_GameView
_onStart
_onResume
_surfaceCreated
_surfaceChanged
_onWindowFocusChanged
이런식으로 이미지 로드 하는 부분 완료가 안되고 onWindowFocusChanged 후 정지되어버립니다.
많은 이미지를 한번에 로딩하다보니까 뭔가 문제가 발생하는 것 같은데
원인이 정확히 뭔지, 어떻게 수정을 해야하는지 모르겠네요 ㅠㅠ
게임 루프의 타이머 제어는 다음과 같이 sleep을 사용하고 있는데
이부분이 문제가 될 여지가 있나요??
요즘 anr 팝업때문에 미치겠네요 ㅠㅠ
혹시 몰라 log 파일도 첨부합니다.
app 구동 시 이미지 로딩을 위한 스레드를 하나 생성하고
로딩 중엔 프로그레스 다이얼 로그를 띄워 로딩중을 알리도록 하였습니다.
public void createThreadAndDialog() { if(Language == KOR) dialog = ProgressDialog.show(mContext, "AppName", "로딩중입니다. 잠시만 기다려주세요.", true); else dialog = ProgressDialog.show(mContext, "MM", "Loading. Please wait...", true); Thread loadThread = new Thread(new Runnable() { public void run() { //이미지를 로드하거나 이미지 작업과 같은 시간이 많이드는 작업을 한다. loadImgProgress(); // 이미지 로드 if(LOG_FLAG) Log.d("[debug]", "_img_End"); dialog.dismiss(); dialog = null; initSounds(); // 사운드 로드 - soundpool 사용 if(LOG_FLAG) Log.d("[debug]", "_sound_End"); handler.sendEmptyMessage(0); } }); loadThread.start(); } private Handler handler = new Handler() { public void handleMessage(Message msg) { if(LOG_FLAG) Log.d("[debug]", "_Handler"); isLoading = true; // 이미지 로딩 완료 체크 플레그 if(!isExit) { thread.setRunning(true); thread.start(); } } };
위 스레드는 이미지와 사운드 리소스 로딩만을 해주도록 만들어주었고(anr 팝업 문제가 생겨서 게임 스레드쪽에 있던걸
따로 스레드를 만들어주었습니다.) 리소스 로딩이 완료되면 게임 스레드(surfaceview쪽)를 start하도록 구현하였습니다.
그런데 어플 구동 테스트를 해보니 간혹가다가 프로그레스 다이얼로그가 보여진 후 게임으로 넘어가질 않는 현상이
발생합니다.
- 현상 1 : 프로그레스 다이얼로그가 뜬 상태로 진행 안됨
- 현상 2 : app 시작 시 프로그레스 다이얼로그도 안뜨고 그냥 까만 화면으로 정지
로그상에 특별한 에러 메세지도 없고 자주도 아니고 가끔가다가 발생을 하고 있습니다.
lifecycle 관련 메서드쪽에 로그를 찍어보니 정상적일땐
12-18 12:46:16.765: DEBUG/[debug](14926): _onCreate
12-18 12:46:16.780: DEBUG/[debug](14926): _GameView
12-18 12:46:16.952: DEBUG/[debug](14926): _onStart
12-18 12:46:16.952: DEBUG/[debug](14926): _onResume
12-18 12:46:17.194: DEBUG/[debug](14926): _surfaceCreated
12-18 12:46:17.194: DEBUG/[debug](14926): _surfaceChanged
12-18 12:46:19.812: DEBUG/[debug](14926): _img_End // 이미지 로드 완료
12-18 12:46:19.819: DEBUG/[debug](14926): _onWindowFocusChanged
12-18 12:46:21.046: DEBUG/[debug](14926): _sound_End // 사운드 로드 완료
12-18 12:46:21.046: DEBUG/[debug](14926): _Handler
12-18 12:46:21.054: DEBUG/[debug](14926): _run
위와같이 타고 들어오고
문제가 발생할땐
_onCreate
_GameView
_onStart
_onResume
_surfaceCreated
_surfaceChanged
_onWindowFocusChanged
이런식으로 이미지 로드 하는 부분 완료가 안되고 onWindowFocusChanged 후 정지되어버립니다.
많은 이미지를 한번에 로딩하다보니까 뭔가 문제가 발생하는 것 같은데
원인이 정확히 뭔지, 어떻게 수정을 해야하는지 모르겠네요 ㅠㅠ
게임 루프의 타이머 제어는 다음과 같이 sleep을 사용하고 있는데
이부분이 문제가 될 여지가 있나요??
요즘 anr 팝업때문에 미치겠네요 ㅠㅠ
class MingleThread extends Thread{ @Override public void run() { if(LOG_FLAG) Log.d("[debug]", "_run"); while (mRun) { Canvas cv = null; long beforeTime = System.nanoTime(); try { if(_GamePause == 0) { cv = mSurfaceHolder.lockCanvas(null); // 백버퍼에 그린다 synchronized (mSurfaceHolder) { if(c == null) { c = cv; } gt_timer(); CheckTouch(); } } }finally{ if(cv != null) { mSurfaceHolder.unlockCanvasAndPost(cv); // 프론트 버퍼로 출력 } } sleepTime = mTimer-((System.nanoTime()-beforeTime)/1000000L); try { if(sleepTime>0){ Thread.sleep(sleepTime); } } catch (InterruptedException ex) { } } } public void setRunning(boolean b) { mRun = b;
혹시 몰라 log 파일도 첨부합니다.