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

Surfaceview에 대하여 질문드립니다.

0 추천

혼자 게임 개발을 해보고 있는데요. surfaceview를 이용해 퍼즐 게임을 개발중입니다.

게임 플레이 도중에 뒤로가기를 누르면 스테이지 선택화면으로 돌아갈려고 합니다.

activity에서 onBackPressed를 구현하여 finish()를 통해서 뒤로 가지는것 까지 확인을 했습니다.

하지만 스테이지 선택화면에서 1~2초간의 터치가 안되는 현상이 발생해서 로그를 찍어봤더니

backPress가 눌렸을 때 onBackPressed함수와 onPause함수는 바로 호출이 되는 방면, surfaceDestroyed 함수가 1초 가량 늦게 호출이 되고, 이 함수가 호출이 되기전까지는 그 전 액티비티에서의 터치가 막히는 것이였습니다.

surfaceview.setVisibility(View.INVISIBLE)를 통해서 빠르게 종료를 시키면 화면상에 깜박이는것처럼 보이고, 1초의 늦은 호출이 좀 더 줄여드는 것일 뿐 완벽한 해결이 되지가 않습니다.

혹시나 메모리를 많이 먹어서 그런가 싶어서 가지고 있는 surfaceview예제를 새 프로젝트에 한개의 이미지만 띄워서 테스트를 해봤는데, 여전히 같은 상황입니다.

 

밑에 가지고 있는 surfaceview 예제를 올립니다. 해결방법좀 알려주세요ㅠㅠ

public class SurfaceViewTest extends SurfaceView implements SurfaceHolder.Callback {
    Context mContext;
    SurfaceHolder mHolder;
    ImageThread mThread;
    Canvas mCanvas = null;

    public SurfaceViewTest(Context context, AttributeSet attr) {
        super(context, attr);
        mContext = context;
        mHolder = getHolder();
        mHolder.addCallback(this);
    }

    @Override
    public void surfaceCreated(SurfaceHolder surfaceHolder) {
        // Surface가 만들어질 때 호출됨
        mThread = new SurfaceViewTest.ImageThread();
        mThread.start();
    }

    @Override
    public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) {
        // Surface가 변경될 때 호출됨
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
        // Surface가 종료될 때 호출됨ground.png
        try {
            Log.d("backPressTest","surfaceDestroyed()");
            mThread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    class ImageThread extends Thread {
        Bitmap test;
        private ImageThread() {
            test = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ground);
            test = Bitmap.createScaledBitmap(test, (int) 100, (int) 100, true);
        }

        private void doDraw() {
            mCanvas.drawBitmap(test,0,0,null);
        }
        public void run() {
                while (true) {
                    mCanvas = mHolder.lockCanvas();
                    try {
                        synchronized (mHolder) {
                                doDraw();
                        }
                    }
                    finally {
                        if (mCanvas == null) return;
                        mHolder.unlockCanvasAndPost(mCanvas);
                    }
            }
        }
    }
}

 

아래는 backPress시 로그입니다. 보시는바와 같이 surfaceDestroyed와 대략 1초정도의 차이가 생깁니다.

2019-10-06 19:21:48.692 15866-15866/test D/backPressTest: onBackPressed()
2019-10-06 19:21:48.693 15866-15866/test D/backPressTest: onPause()
2019-10-06 19:21:49.530 15866-15866/test D/backPressTest: surfaceDestroyed()

IU (260 포인트) 님이 2019년 10월 6일 질문

2개의 답변

0 추천
 
채택된 답변

화면이 종료되었는데. ImageThread run 이 계속 도는 중이라 문제가 발생하는 것으로 생각됩니다.

아래와 같이 별도 값을 설정해서, onBackPressed 가 불릴 때 mThread.onBackPressed(); 를 불러 Thread동작이 끝나게 변경 해 보세요.

class ImageThread extends Thread {

    boolean isRun;

    private ImageThread() {

        isRun = True;

       ....

    }

    public void onBackPressed() {

        isRun = false;

    }

    public void run() {

        while(isRun) {

            ....

        }

    }

}

 

익명사용자 님이 2019년 10월 7일 답변
IU님이 2019년 10월 7일 채택됨
와 감사합니다 ㅠㅠ 며칠을 해결 못했었는데 막상 보니까 이렇게 간단한거였다니..ㅠㅠ
0 추천
Thank you for your post. This article gives me lots of advice it was very helpful for me!
mika 님이 2019년 10월 16일 답변
aucd29님이 2019년 10월 17일 수정
...