Ich habe eine SurfaceView-Erweiterung, in der die nackten Knochen wie in Lunar Lander Beispiel. Das heißt, die Methode run()
der Zeichnung Thread
ist im Wesentlichen:
Und das Thread
wird ordnungsgemäß gestoppt, wenn die Oberfläche zerstört wird:
Auf Geräten, die ich bisher getestet habe (HTC Desire, Desire HD und Archos 101, zwischen denen OS 2.2 und 2.3.3 sind, wenn ich mich recht erinnere), gab es nie ein Problem mit dem Obigen. Das heißt, wenn die Oberfläche zerstört wird, weil der Benutzer Activity
zurücknimmt oder ein weiterer Activity
oben aufgerufen wird, stellt der Code innerhalb von surfaceDestroyed()
immer sicher, dass mSurfaceHolder.lockCanvas()
niemals aufgerufen würde, um% co_de zurückzugeben %.
Der Unterschied zu meinem neuen HTC One X, auf dem Android 4 / ICS läuft, ist jedoch, dass während des Aufrufs der Methode null
(dh der Code innerhalb dieser Methode noch ausgeführt wird) meine Zeichnung surfaceDestroyed()
würde ein Thread
canvas von null
erhalten. Dies würde natürlich einen Anwendungsabsturz verursachen. Auf meinem One X passiert das jedes jedes Mal, wenn die Oberfläche zerstört wird - sei es durch Drehen des Telefons, Zurücksetzen von mSurfaceHolder.lockCanvas()
usw.
Ich bin darüber verwirrt, weil ich den Eindruck hatte, dass Activity
eine nicht mSurfaceHolder.lockCanvas()
null
zurückgeben sollte, bis Canvas
tatsächlich exited ist. Ja, genau das sagt der Javadoc:
surfaceDestroyed()
Meine Lösung ist jetzt, einfach nach This is called immediately before a surface is being destroyed. After returning from this call, you should no longer try to access this surface. If you have a rendering thread that directly accesses the surface, you must ensure that thread is no longer touching the Surface before returning from this function.
zu suchen. Das funktioniert gut:
Aber, irgendwelche Ideen, warum ich das plötzlich für Android 4 / ICS machen muss?
Um meinen Kommentar näher auszuführen, scheint es, dass es ein Bug-Ticket für diese Verhaltensänderung gibt, die Sie hier finden: Ссылка . Wenn es dich betrifft, könnte es sich lohnen, es anzustarren, nur damit es seine Wichtigkeit ein wenig erhöht!
Persönlich habe ich das selbst gesehen, nur indem ich das Beispiel mit dem Mondlandeten benutzt habe, das mit dem neuesten Android SDK geliefert wird. Ich lege es auf mein HTC Sensation XE (4.0.3) und bei einer Orientierungsänderung bekomme ich einige leere Bilder zurück, bevor die Oberfläche zerstört wird.
Die von mir verwendete Problemumgehung besteht also lediglich darin, zu überprüfen, ob die Zeichenfläche nicht null ist, bevor Sie sie an meine Aktualisierungs- und Rendermethoden übergeben.
Andy
Ich habe ein kleines Experiment gemacht. Ich setze einige Benachrichtigungsflags in surfaceDestroyed()
methode wie folgt:
Was ich herausgefunden habe, ist die Tatsache, dass die nullPionterExceptionOccurs
nach der ersten, aber vor der zweiten Flagge auftritt. Das bestmögliche Ergebnis für Ihre Frage ist, dass Sie den Canvas-Bereich sperren, wenn die alte Ansicht erreichbar ist. Sie zeichnen darauf, aber in der Zwischenzeit ändert sich der Bildschirm. Wenn die Leinwand entsperrt wird, gibt es keinen Platz mehr, um die Ergebnisse anzuzeigen - der Fehler wird verursacht.
P.S. Spielen Sie ein wenig mit Lunar Lander von Beispiel-Android-Codes und versuchen Sie, den Bildschirm zu drehen, während das Spiel funktioniert. Wenn der Fehler auftritt, schauen Sie einfach, wie die Hintergrund-Bitmap gezeichnet werden soll. Sie werden feststellen, dass sich die Bildschirmausrichtung geändert hat, aber das Programm hat versucht, eine Bitmap zu zeichnen, als ob nichts passiert.
Tags und Links android surfaceview