Crashed Lander

LunarLander Bug

Wie vermutlich einige andere Leute auch hab ich in Sachen animierte Spiele für das Android Betriebssystem mich am LunarLander Beispiel bedient. Er zeigt eigentlich alle grundlegenden Sachen recht gut auf, jedoch hat er einen kleinen Schönheitsfehler. Sobald man das Programm minimiert(SMS beantworten usw.)  und wieder aufruft stürzt das Programm ab.

Ungefähr so sollte dann die Debug-Ausgabe von LogCat aussehen:

java.lang.IllegalThreadStateException: Thread already started.
at java.lang.Thread.start(Thread.java:1227)
[...]
at android.view.SurfaceView.updateWindow(SurfaceView.java:543)
at android.view.SurfaceView.onWindowVisibilityChanged(SurfaceView.java:213)
at android.view.View.dispatchWindowVisibilityChanged(View.java:4027)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:720)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:720)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:720)
at android.view.ViewRoot.performTraversals(ViewRoot.java:785)
at android.view.ViewRoot.handleMessage(ViewRoot.java:1862)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3806)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
at dalvik.system.NativeStart.main(Native Method)

Ich hab ein wenig zu dem Problem im Internet gesucht und die Lösung von Wonton-Games ist die Variante, die mir am meisten zusagt.

Er erklärt auch in seinem Artikel sehr detailiert woher das Problem rührt. Im Grunde hängt es mit dem Lebenslauf einer Activität in Android zusammen(genaueres hier). Und zwar, wenn man das Programm minimiert speichert Android alle Daten zur Aktivität und die, die in onSaveInstanceState() übergeben werden in einem Bundle in der Annahme, dass onCreate(Bundle savedInstance) aufgerufen wird. Da aber Android beim zurückkehren feststellt, dass bereits ein SurfaceView bereits erstellt wurde, wird dieser Schritt nicht ausgeführt sondern ruft direkt surfaceCreated(). Somit werden zum einen die gespeicherten Information nicht ausgelesen und weiterhin wird der bereits “terminierte” Thread versucht neustarten mit thread.start().

Wonton schlägt vor surfaceCreated() zu überarbeiten, sodass die Funktion wie im folgenden aussieht.
public void surfaceCreated(SurfaceHolder holder) {
if(thread.getState()== Thread.State.TERMINATED){
thread = new LunarThread(mHolder, mContext, mHandler);
thread.setRunning(true);
thread.start();
}else {
thread.setRunning(true);
thread.start();
}
}

Da in diesem Beispiel der LunarThread komplett neu erstellt wird kommt es dazu, dass alle Variablen und Daten aus dem Thread zurückgesetzt werden. Um Daten-Verlust zu vermeiden bietet es sich an, wie in Wonton’s Blogeintrag vorgeschlagen alle Variablen und Resourcen im LunarView zu speichern und Von LunarThread darauf zuzugreifen.
class LunarView extends SurfaceView implements SurfaceHolder.Callback {
Variablen
Resourchen
usw.
class LunarThread extends Thread {
}

Alternativ, wenn man LunarThread in einer seperaten Datei speichern will, bietet es sich an eine load() und save() funktionen zu implementieren, die beim Minimieren und beim Laden der Aktivität aufgerufen wird. Hier bietet sich onSaveInstanceState() zum speichern und onRestoreInstanceState() oder onCreate() zum laden an. Jedoch muss man beim Laden bedenken, dass onRestoreInstanceState() zumeist nur beim Rotieren aufgerufen wird. Hier sollte man in der surfaceCreated-Funktion auch überprüfen, ob eventuell Daten gespeichert wurden und diese dann dem neu erstellten Thread übergeben.

Für weitere Informationen verweise ich auf diesen Blog-Eintrag, der mir Quelle und Inspiration war und ich danke dem Autor zutiefst, dass er dieses Thema so breit darlegte.

Published by

Le m0keu

Developer of Drop Dots, an Android App available on Google Play!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>