2011-02-10 8 views
6

He estado investigando métodos alternativos para guardar los datos de mi juego entre turnos, y me pregunto si alguien puede señalarme en la dirección correcta.El mejor método para guardar datos: preferencias, sqlite, serializable u otros?

Tengo aproximadamente 32k de datos que se deben guardar durante OnPause. Descarté las preferencias debido a la gran cantidad de datos. Pasé unos días jugando con SQLite, pero no pude obtener los datos para guardar en menos de dos segundos (aunque el tiempo ciertamente no se ha desperdiciado).

He decidido usar la base de datos para cargar datos constantes al comienzo del juego. Esto sin duda hará que sea más fácil ajustar varios parámetros y valores predeterminados en el juego. Pero esto todavía me deja buscando el método ideal para escribir datos.

Los datos que se deben guardar son básicamente nueve apariciones de clase A y nueve ocurrencias de clase B. Soy un mes intensivo en la curva de aprendizaje de Android (y los matices de Java, procedentes de un fondo C++) y he estado buscando en Google como loco. Esto trajo dos posibilidades a la mente -

1) serialización (ObjectOutputStream)

pensé que esto sería la solución perfecta, pero, después de haber leído varios otros puestos con respecto al tema, se reúnen que no es muy recomendable en el Plataforma Android debido a la velocidad y asignaciones de memoria que provocan el colector de basura en una rabia potencial.

2) Clase DataOutputStream

Mi pensamiento actual es añadir Cargar y Guardar las funciones de ambas clases y utilizar DataOutputStream y DataInputStream llamadas en ellos para escribir y leer los datos respectivamente.

Los datos en las clases son primitivos (cadenas y detalles en su mayoría) y matrices de primitivas, por lo que no hay nada demasiado complicado para descomponerse. ¿Esta segunda solución parece una buena y viable? ¿O hay otras soluciones que aún desconozco?

+0

La consideración principal a tener en cuenta es que escribir en flash puede ser una operación larga, independientemente del tamaño de los datos. Incluso escribir 1 byte puede tomar una cantidad de tiempo notable. Por lo tanto, asegúrese de que su solución almacena temporalmente todos los datos y los escribe en la menor cantidad de operaciones posible. – Jems

+1

Gracias por el consejo. He ido con el método DataOutputStream y el tiempo necesario para escribir los datos ahora es insignificante (aproximadamente 0.1 segundos). Sin embargo, me alegro de que me haya desviado de las bases de datos SQLite, ya que seguramente serán muy útiles :) – Rok

Respuesta

2

Debe utilizar una tarea asíncrona para guardar los datos, que usaron este método para captar mejores puntuaciones en el iniciar un juego:

new HighscoreTask().execute(this); 

la tarea asíncrona se ve así:

public class HighscoreTask extends AsyncTask<MainView, Void, Void> { 

    protected void onPreExecute() { 
    } 

    protected void onPostExecute(final Void unused) { 
    } 
    @Override 
    protected Void doInBackground(MainView... params) { 
     HighScoreFactory.syncScores(); 
     return null; 
    } 
} 

Todos la interacción de la base de datos ocurre en HighScoreFactory.syncScores() esto puede tomar todo el tiempo que necesite porque ocurre en segundo plano. En mi caso, envía una solicitud HTTP a un servidor externo y las carga en una base de datos. Nunca causó ningún problema y funciona a la perfección.

+0

Gracias - Sin duda lo tendré en cuenta. Estoy guardando los datos del juego como archivos binarios sin formato que ahora funcionan * mucho * más rápido. Pero definitivamente investigará Async ya que algunas personas lo han sugerido ahora. – Rok

1

¿Has probado insertar datos en la base de datos en la transacción?

try{ 
db.beginTransaction(); 

//here insert data to database  

db.setTransactionSuccessful(); 
} finally { 
db.endTranscation(); 
} 

Eso puede acelerar el funcionamiento.

+0

Experimenté con el uso de transacciones hasta el punto de que todas mis escrituras se realizaron en una sola transacción, esto trajo el tiempo de 8 segundos a 2 segundos. Parecía golpear una pared de ladrillo en ese punto y, dar o tomar una décima de segundo, no podía bajar más. Esta es la primera codificación SQLite que he hecho, pero mi sensación era que no podría obtenerla más rápido (aunque me gustaría que me dijeran lo contrario) – Rok

0

Cree un nuevo subproceso que realice la escritura de datos utilizando Context.openFileOutput (String name, int mode) con esto como el contexto. A continuación, puede escribirlo en segundo plano con el nuevo hilo y recuperarlo con: Context.openFileInput (String name) de nuevo con esto como el contexto. Espero que esto ayude.

2

¿Por qué tiene un límite de 2 segundos en la escritura de su base de datos? Si es solo por la capacidad de respuesta de UI, entonces hay otro enfoque que puede tomar.

En realidad, no tiene que realizar el guardado dentro de su método en sí, podría iniciar un nuevo Thread que realmente lo guarda para usted.

private void backgroundSave(){ 
    Thread backgroundThread = new Thread() { 
     @Override 
     public void run() { 
      //do save here 
     } 
    }; 
    backgroundThread.start(); 
} 

@Override 
protected void onPause() { 
    super.onPause(); 
    backgroundSave(); 
} 

Como alternativa, puede utilizar AsyncTask para esto.

Es posible que tenga que considerar el caso cuando un usuario intenta reiniciar su aplicación antes de que se complete el guardado, pero eso no debería ser demasiado difícil de tener en cuenta.

+1

Los datos que se guardan están en uso constante durante todas las actividades. La idea de asignar el guardado a un hilo de fondo suena buena, pero no he tenido tiempo de familiarizarme con la resolución de problemas de sincronización. Es algo que definitivamente examinaré tan pronto como tenga la oportunidad. Por ahora, descubrí que puedo escribir los datos en un archivo binario en alrededor de 0.1 segundos. Aunque aprecio el consejo. Mucho que aprender, tan poco tiempo ... :) – Rok

Cuestiones relacionadas