Правильная приостановка потоков onPause() и onResume() с SurfaceView и Thread в Android

Для запуска игр, созданных на Android, я использовал GamePanel, содержащий методы onDraw () и onTouch (). Я также использовал класс GameThread, который неоднократно вызывает onDraw () и update ().

Моя деятельность создает GamePanel, а моя GamePanel создает GameThread.

Мой onPause () просто устанавливает условие в цикле while внутри потока, run, в false. Мой onResume () просто устанавливал это значение равным true, однако это давало бы мне ошибку принудительного закрытия (см. Правку №1) каждый раз, когда я пытался возобновить приложение.

Так что вместо того, чтобы решить проблему, я просто заново создал поток,

thread = new GameThread(getHolder(), this);

Это решило часть проблемы, позволив мне свернуть приложение, а затем снова открыть его без проблем. Однако, когда я был в приложении и заблокировал свой телефон, а затем разблокировал его (включив и выключив экран), поток не запустился. Это была бы просто моя игра в замороженном состоянии.

Я знаю, что мое решение этой проблемы чрезвычайно прикольное, и я хотел бы узнать более приемлемый и чистый способ сделать все это.

Вот код (я пропустил несколько строк, которые не были актуальны):

GameActivity:

void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    gamePanel = new MainGamePanel(this);
    setContentView(gamePanel);

}
protected void onPause() {
    super.onPause();
    gamePanel.shutDown();

}
protected void onResume() {
    super.onResume();
    gamePanel.startUp();
}

GamePanel

public MainGamePanel(Context context) {
    super(context);
    getHolder().addCallback(this);                  //adding the callback (this) to the surface  holder to intercept events
    thread = new GameThread(getHolder(), this);     // create the game loop thread
    setFocusable(true);                             // make the GamePanel focusable so it can handle events
}
public void startUp() {
    thread = new GameThread(getHolder(), this);
}

public void shutDown() {
    thread.setRunning(false);
}

GameThread

public GameThread(SurfaceHolder surfaceHolder, MainGamePanel gameView) {
    this.surfaceHolder = surfaceHolder;
    this.gameView = gameView;
    this.run = true;
}
public void setRunning(boolean run) {
    this.run = run;
}
public void run() {
    Canvas c;//
    while (run) {
        c = null;
        try {
            c = surfaceHolder.lockCanvas(null);
            synchronized (surfaceHolder) {                  
                gameView.update();
                gameView.onDraw(c);
            }
        } finally {
            if (c != null) {
                surfaceHolder.unlockCanvasAndPost(c);
            }
        }
    }
}

Дайте мне знать, если вам нужна дополнительная информация или как я могу сделать мой вопрос более ясным (также, я представил мой код в понятной усадьбе?).

Небольшая помощь будет иметь большое значение. Спасибо заранее, если вы можете дать какие-либо предложения.

-EDIT #1--

Это было моей ошибкой, когда я приблизился.

12-23 14:01:34.288: E/AndroidRuntime(9484): java.lang.IllegalThreadStateException: Thread already started.

-EDIT #2--

Я попробовал то, что вы сказали, и изменил мой метод run () на:

@Override
public void run() {
    Canvas c;
    while (true) {
        if (run) {/* run game thread */
            c = null;
            try {
                c = surfaceHolder.lockCanvas(null);
                synchronized (surfaceHolder) {
                    gameView.update();
                    gameView.onDraw(c);
                }
            } finally {
                if (c != null) {
                    surfaceHolder.unlockCanvasAndPost(c);
                }
            }
        } else {
            try {
                Thread.sleep(100);
            } catch (Exception e) {
            }
        }
    }
}

Это сработало, когда я заблокировал свой телефон, но когда я свернул приложение и снова открыл его, у меня появился черный экран и через несколько секунд всплывающее окно с надписью "MyApp не отвечает. Хотите закрыть его?". Я проверил, где он дошел, и он, кажется, дошел до onPause () и shutDown (), но он так и не дошел до onResume ();. Кроме того, иногда он даже вызывает update () после вызова onPause () или shutDown (), что странно. (Получил информацию от LogCat)

0 ответов

Другие вопросы по тегам