Для запуска игр, которые я создал на Android, я использую GamePanel, содержащую методы onDraw() и onTouch(). Я также использовал класс GameThread, который многократно вызывает onDraw() и update().
Моя активность создает экземпляр GamePanel, а моя GamePanel создает экземпляр GameThread.
Мой onPause() просто устанавливает условие в цикле while внутри потока run на false. Мой onResume() просто устанавливал это значение равным true, однако это приводило к ошибке принудительного закрытия (см. редактирование #1) каждый раз, когда я пытался возобновить работу приложения.
Поэтому вместо того, чтобы решить проблему, я просто повторно создал поток,
thread = new GameThread(getHolder(), this);
Это решило часть проблемы, позволив мне свернуть приложение, а затем снова открыть его без проблем. Однако, когда я был в приложении и заблокировал свой телефон, а затем разблокировал его (включив и выключив экран), поток никогда не запускался. Это была бы просто моя игра в замороженном состоянии.
Я знаю, что мое решение проблемы очень странное, и я хотел бы узнать более приемлемый и чистый способ сделать все это.
Вот код (я пропустил несколько строк, которые не кажутся важными):
Игровая активность:
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);
}
}
}
}
Дайте мне знать, если вам нужна дополнительная информация или как я могу сделать свой вопрос более ясным (также, представил ли я свой код в понятной манере?).
Небольшая помощь будет иметь большое значение. Заранее спасибо, если вы можете дать какие-либо предложения.
--РЕДАКТИРОВАНИЕ №1--
Это была моя ошибка в журнале, когда я получил принудительное закрытие.
12-23 14:01:34.288: E/AndroidRuntime(9484): java.lang.IllegalThreadStateException: Thread already started.
--РЕДАКТИРОВАНИЕ №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)