2009-03-25 5 views
1

Kommen Sie einfach zum Polieren meiner Anwendung und damit es fortsetzen, nachdem der Benutzer verlassen hat. Wenn die Anwendung wiederhergestellt wird, bekomme ich eine IllegalThreadStateException, was ziemlich nervig ist. Dieses Problem ist im Beispiel google gibt Lunar Lander. Hat jemand eine Möglichkeit gefunden, die Arbeit bei der Verwendung von SurfaceView wiederherzustellen?Android IllegalThreadStateException in LunarLander

Antwort

3

Ich glaube, das ergibt sich aus einer Disparität in wie die Oberfläche und die Aktivität behandelt werden. Wenn Sie die LunarLander-Anwendung verlassen, wird die Oberfläche zerstört (Aufruf von destroyed), aber die Aktivität wird nur pausiert (Aufruf von onPause). Wenn die Aktivität wieder aufgenommen wird, wird die Oberfläche erstellt (durch Aufruf von SurfaceCreated) und es wird versucht, den Zeichnungs-Thread erneut zu starten.

Das bedeutet, dass das Erstellen des Threads mit dem Lebenszyklus der Aktivität geschieht und das Löschen des Threads mit dem SurfaceView-Lebenszyklus erfolgt, die nicht immer übereinstimmen, also die IllegalThreadStateException. Die Lösung wäre, den Thread an den einen oder den anderen Lebenszyklus zu binden, nicht an beide.

Ich denke, this thread schlägt eine mögliche Lösung, obwohl ich nicht weiß, ob es funktioniert.

+0

Ich habe versucht, den Link und es funktioniert nicht. Muss ich den Thread in SurfaceCreated instanziieren? Ich habe das versucht, aber das Programm stürzt ab. –

+0

Der verknüpfte Thread scheint nicht sehr nützlich zu sein, aber wie Soonil beschreibt, habe ich die Thread-Lebensdauer so geändert, dass sie der Surface-Lebensdauer entspricht, und es funktioniert. (Ich habe das auch mit LunarLander versucht und sie haben viel zu viel Spiellogik in ihrem Thread-Objekt, also ist es keine triviale Lösung.) – idbrii

2

In meinem eigenen Test erstelle ich den Zeichenthread in der Methode "toilecated()", und das löst das Problem vollständig. Dies ist meine Methode Umsetzung:

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

So in dem Code, wenn surfaceDestroyed() genannt wird, setzt sie mRun auf false und ruft thread.join(). Dies bewirkt, dass der Thread beendet und beendet wird. Wenn die App erneut gestartet wird und surfaceCreated() aufgerufen wird, ruft sie thread.start() auf. Dies ist ungültig, weil der Thread nicht gestartet werden kann, nachdem er beendet wurde.

Zwei Optionen zu beheben:

a) in surfaceCreated() einen neuen Thread starten - wie oben.

b) Oder fügen Sie ein Häkchen in surfaceDestroyed() gegen Activity.isFinishing(), um nur den Thread zu beenden, wenn wahr. Um dies zu tun, umgab ich die while(mRun) im Thread mit einer anderen While-Schleife, die nur auf false gesetzt ist, wenn isFinishing() Wahr zurückgibt.

Verwandte Themen