Android で作成したゲームを実行するために、onDraw() メソッドと onTouch() メソッドを含む GamePanel を使用しています。また、onDraw() と update() を繰り返し呼び出す GameThread クラスも使用しています。
私のアクティビティは GamePanel をインスタンス化し、私の GamePanel は GameThread をインスタンス化します。
私の onPause() は、スレッド run 内の while ループの条件を 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();
}
ゲームパネル
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);
}
ゲームスレッド
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(); には到達しませんでした。また、onPause() または shutDown() を呼び出した後に update() を呼び出すこともありますが、これは奇妙です。(LogCat から情報を入手)