Mein Spiel speichert seinen Status nach einem festgelegten Intervall in einer Datei im internen Speicher des Spiels / der App. Wenn mein Spiel vom Benutzer oder Betriebssystem beendet oder abgestürzt wird, schreiben wir den aktuellen Spielstatus in diese Datei. Das Schreiben von Dateien nach dem Fixintervall funktioniert einwandfrei, aber wenn das Spiel vom Betriebssystem oder Benutzer abgestürzt ist, schlägt der Schreibvorgang fehl. Ein Betriebsfehler führt zu einem unvollständigen oder leeren Spielstatus, dh es werden überhaupt keine Daten in die Datei geschrieben. Ich habe mehrere Lösungen mit Android-Dienst ausprobiert. Falls der Dienst NICHT STICKY ist, wird der Dienst mit der App beendet. Wenn der Dienst dagegen STICKY ist, wird er neu gestartet, aber die ursprünglich mit dem Dienst verknüpfte Absicht ist null oder neu.
Die Frage ist, wie kann ich meine Daten (könnte ~ 2-3 MB groß sein) vollständig im internen Speicher ablegen, wenn mein Spiel / meine App vom Benutzer / Betriebssystem beendet wird?
Antworten:
Ich würde vorschlagen, Ihren Speicherstatus doppelt gepuffert zu schreiben, wie es in der Vergangenheit bei Konsolentiteln üblich war (bei denen das Entfernen der Speicherkarte während des Schreibvorgangs und das Schreiben nur langsam vonstatten ging).
Speichern:
Belastung:
Dieser Ablauf stellt sicher, dass immer mindestens eine gültige Speicherung in Ihrem Speicher vorhanden ist, auch wenn die App während des Schreibvorgangs beendet wird. Der Spieler erhält keine der Änderungen im Spielstatus seit dem letzten Speichern, wenn diese Art von Fehler auftritt, muss jedoch nicht erneut gestartet werden.
Zusätzlich sollten Sie unmittelbar nach Schlüsselereignissen (wie In-App-Käufen) zusätzlich zu Ihrer Intervallspeicherung speichern, um das Fenster der Sicherheitsanfälligkeit zu minimieren, in dem ein Absturz / Kill dazu führen würde, dass dieses Schlüsselereignis verloren geht. Dies ist auch ein Schutz gegen Spiel-Exploits (z. B. das erzwungene Beenden der App nach dem Verlust eines Lebens, da Sie wissen, dass Sie den Spielstatus wiederherstellen, bevor Sie ein Leben verloren haben, und es erneut versuchen können). In diesem Fall müssen Sie die Intervallspeicherung natürlich mit einer Logik schützen, die besagt: "Wenn bereits ein Speichervorgang ausgeführt wird, versuchen Sie nicht, den Speichervorgang erneut zu starten."
quelle
java.nio.file.Files.move(Path source, Path target, CopyOption... options)
Umbenennen und Überschreiben kann als atomare Operation erfolgen.sync()
Datei B auf, bevor Sie sie über Datei A verschieben (auch dann gibt es keine vollständigen Garantien, diese sind jedochsync()
recht gut).Android beendet Apps nur im Hintergrund. Müssen Ihre Spieldaten wirklich aktualisiert werden, wenn sich die App im Hintergrund befindet, oder können Sie die Aktualisierung der Daten beenden, bis die App in den Vordergrund zurückkehrt? Sie können Aktualisierungen möglicherweise auch in einem Multiplayer-Spiel zurückstellen, wenn Sie einen Verlauf von Ereignissen oder sogar nur den aktuellen Status abrufen können, wenn die App wieder in den Vordergrund rückt. Dies sollten Sie aus Gründen der CPU-, Netzwerk- und Akkueffizienz ohnehin in Betracht ziehen.
Wenn der Benutzer Ihre App beendet, sollten ausgeführte Dienste angerufen werden
onTaskRemoved
. Ich weiß nicht, was passieren würde, wenn Sie versuchen würden, in dieser Methode viel zu verarbeiten. Ich gehe davon aus, dass Androidkill -9
Ihre App wird, wenn es nicht innerhalb einer bestimmten Zeit zurückkehrt .quelle