Правильная приостановка потоков 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)