2009-03-25 2 views
1

私のアプリケーションを研磨し、ユーザーが放置した後に再開するようになりました。アプリケーションが復元すると、私はIllegalThreadStateExceptionを取得します。これはかなり厄介です。この問題は、googleの例であるLunar Landerにあります。 surfaceViewを使用しているときに誰かが作業を復元する方法を見つけましたか?LunarLanderのAndroid IllegalThreadStateException

答えて

3

これは、サーフェスとアクティビティの処理方法の相違に起因すると考えられます。 LunarLanderアプリケーションを終了すると、サーフェスは破棄されます(surfaceDestroyedを呼び出す)が、アクティビティは一時停止(onPauseを呼び出す)するだけです。アクティビティが再開されると、サーフェスが作成され(surfaceCreatedを呼び出す)、描画スレッドを再び開始しようとします。

これは、スレッドの作成はアクティビティのライフサイクルで行われ、必ずしも対応しないSurfaceViewのライフサイクルでスレッドが破棄されるため、IllegalThreadStateExceptionが発生します。解決策は、スレッドを1つのライフサイクルまたは他のライフサイクルに結びつけることであり、両方を結合することではありません。

私はthis threadが解決策を提案していると思いますが、それがうまくいくかどうかわかりません。

+0

リンクを試しても機能しません。私はsurfaceCreatedのスレッドをインスタンス化する必要がありますか?私はこれを試みたが、プログラムがクラッシュする。 –

+0

リンクされたスレッドはあまり役に立たないようですが、Soonilが説明しているように、Surfaceライフタイムと一致するようスレッドの寿命を変更しました。 (私はLunarLanderでこれをやろうとしましたが、彼らはThreadオブジェクトにあまりにも多くのゲームロジックを持っているので、簡単な修正はありません。) – idbrii

2

私自身のテストでは、surfaceCreated()メソッドで描画スレッドを作成します。これにより、問題は完全に解決されます。これは私のメソッドの実装です:

@Override 
public void surfaceCreated(SurfaceHolder arg0) { 
    _thread = new DrawThread(getHolder()); 
    _thread.setRunning(true); 
    _thread.start(); 
} 
0

だからsurfaceDestroyed()が呼び出されるコードで、それがfalseにmRunを設定し、thread.join()を呼び出します。これにより、スレッドが完了して終了します。アプリが再び起動され、surfaceCreated()が呼び出されると、thread.start()が呼び出されます。これは、スレッドが終了した後にスレッドを開始できないため無効です。修正する

つのオプション:

A)surfaceCreated()に新しいスレッドを開始します - 上記のように。

b)または、真の場合はスレッドを終了するには、surfaceDestroyed()Activity.isFinishing()に対してチェックします。これを行うには、スレッド内のwhile(mRun)を別のwhileループで囲みました。これは、isFinishing()がtrueを返す場合にのみfalseに設定されます。

関連する問題