Mi juego guarda su estado después de un intervalo fijo en un archivo en el almacenamiento interno del juego / aplicación. Cuando el usuario o el sistema operativo matan o bloquean mi juego respectivamente, escribimos el estado actual del juego en ese archivo. La escritura de archivos después del intervalo de corrección funciona bien, pero cuando el sistema operativo o el usuario bloquean / matan el juego, la operación de escritura de archivos falla. El fallo de la operación da como resultado un estado de juego incompleto o un estado de juego vacío, es decir, ningún dato escrito en el archivo. He intentado múltiples soluciones usando el servicio de Android, en caso de que el servicio sea NO STICKY, el servicio se elimina con la aplicación. Por otro lado, si el servicio es STICKY, se reinicia pero la intención que se adjuntó inicialmente con el servicio es nula o nueva.
La pregunta es: ¿cómo puedo guardar mis datos (podría ser ~ 2-3MB) completamente en el archivo en el almacenamiento interno cuando el usuario / sistema operativo mata mi juego / aplicación?
Respuestas:
Sugeriría escribir su estado de guardado de una manera de doble búfer, como era común para los títulos de consola en el pasado (donde tenía que hacer frente a la extracción de la tarjeta de memoria a mitad de la escritura y las escrituras eran lentas).
Salvar:
Carga:
Este flujo funcionará para garantizar que siempre haya al menos un guardado válido presente en su almacenamiento, incluso si la aplicación se cierra a mitad de la escritura. El jugador no obtendrá ninguno de los cambios en el estado del juego desde el guardado anterior si se produce ese tipo de falla, pero no tendrá que comenzar de nuevo.
Además, debe guardar inmediatamente después de los eventos clave (como las compras en la aplicación), además de guardar el intervalo, para minimizar la ventana de vulnerabilidad en la que un bloqueo / muerte causaría la pérdida de ese evento clave. Esto también es protección contra las vulnerabilidades del juego (por ejemplo, matar a la fuerza la aplicación después de perder una vida, porque sabes que volverás a un estado de juego desde antes de perder una vida y volverás a intentarlo). Por supuesto, si hace esto, debe proteger su intervalo de guardado con una lógica que dice "si un guardado ya está en progreso, no intente comenzar a guardar nuevamente".
fuente
java.nio.file.Files.move(Path source, Path target, CopyOption... options)
Puede cambiar el nombre y sobrescribir como una operación atómica.sync()
al archivo B antes de moverlo sobre el archivo A (incluso entonces no hay garantías completas, perosync()
es bastante bueno).Android solo mata las aplicaciones cuando están en segundo plano. ¿Realmente deben actualizarse los datos del juego cuando la aplicación está en segundo plano, o puede dejar de actualizar los datos hasta que la aplicación vuelva al primer plano? Es posible que pueda diferir las actualizaciones incluso en un juego multijugador, si puede obtener un historial de eventos o incluso solo el estado actual cuando la aplicación vuelve al primer plano. Esto es algo que probablemente debería considerar hacer de todos modos por la eficiencia de la CPU, la red y la batería.
Si el usuario mata su aplicación, los servicios en ejecución deberían recibir una llamada
onTaskRemoved
. No sé qué pasaría si intentaras hacer mucho procesamiento con este método. Espero que si no regresa dentro de cierto tiempo, Android serákill -9
tu aplicación.fuente