android - solo - ¿Cómo puedo conservar un objeto complejo en los reinicios de actividad?
que pasa cuando se reinicia un celular (2)
Estoy buscando una forma que no implique crear una base de datos y escribir el objeto (sobre todo porque a) la API DB de Android es horrible yb) ya que las bases de datos hacen que las actualizaciones de aplicaciones sean una pesadilla, porque no hay soporte decente para aplicar migraciones )
La API de Android es realmente bastante razonable, principalmente porque es una envoltura delgada sobre la API SQLite, y la API SQLite es bastante razonable para una base de datos incrustada. Además, Android proporciona asistencia para actualizaciones de esquema en las actualizaciones de la aplicación, a través de SQLiteOpenHelper
.
Es mucho más rápido de lo que esperaba y, a menos que sus granos transporten grandes cantidades de datos, funciona bastante bien.
He oído hablar de muchos más desarrolladores huyendo de la serialización que gritos de que la gente ha tenido éxito a largo plazo con ella. Justo en los últimos días, aquí en SO #android, tuve un intercambio con alguien que trataba desesperadamente de arrancar la serialización de su aplicación desde la raíz.
Y aún mejor, no tiene que mantener un esquema DB.
Oh sí, tú sí. ¿Qué crees que va a pasar cuando actualices tu aplicación y tu clase se modifique? Hacer la bookkeeping para descubrir cómo deserializar las versiones antiguas de la clase de una nueva versión de una clase es una tarea ardua y es una de las razones por las que los desarrolladores abandonan la serialización. Además, no olvide que la serialización no es transaccional, mientras que SQLite sí lo es.
Supongamos que tengo un objeto Java Bean que es serializable. Quiero almacenarlo de forma segura cuando una actividad se realiza en Destroy () a propósito (es decir, no se llama a onSaveInstanceState ()).
Estoy buscando una forma que no implique crear una base de datos y escribir el objeto (sobre todo porque a) la API DB de Android es horrible yb) ya que las bases de datos hacen que las actualizaciones de aplicaciones sean una pesadilla, porque no hay soporte decente para aplicar migraciones )
Pensé en serializar el objeto en un ByteArrayOutputStream, base64 codificar eso y escribirlo en un archivo SharedPreferences como una cadena. ¿O está demasiado lejos?
ACTUALIZAR
Tal vez esa idea de serializar a cuerdas no era tan mala después de todo, parece funcionar bastante bien. Esto es lo que estoy haciendo ahora:
public static String objectToString(Serializable object) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
new ObjectOutputStream(out).writeObject(object);
byte[] data = out.toByteArray();
out.close();
out = new ByteArrayOutputStream();
Base64OutputStream b64 = new Base64OutputStream(out);
b64.write(data);
b64.close();
out.close();
return new String(out.toByteArray());
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public static Object stringToObject(String encodedObject) {
try {
return new ObjectInputStream(new Base64InputStream(
new ByteArrayInputStream(encodedObject.getBytes()))).readObject();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
en onDestroy () Puedo simplemente escribir la cadena Base64 en un archivo de preferencias, donde es seguro hasta que lo vuelva a leer durante el siguiente lanzamiento de la actividad. Es mucho más rápido de lo que esperaba y, a menos que sus granos transporten grandes cantidades de datos, funciona bastante bien. Y aún mejor, no tiene que mantener un esquema DB.
Aún así, tengo curiosidad sobre cómo otros hacen esto.
También estaba buscando un buen enfoque para unificar los frijoles o estados de actividad. Todos sabemos cuánto cuesta onStoreInstanceState () y onRestoreInstanceState () de Activity.
Mis actividades simplemente almacenan sus estados en onPause () y los restauran en onCreate () hooks del ciclo de vida a través de la serialización directa de objetos.
La serialización a través de un String como usted lo hace, por supuesto, es posible pero menos adecuada para Big Data y causa una gran sobrecarga. Además, las preferencias están realmente allí para almacenar las preferencias, no los datos :) Lamentablemente, Parcelable / Parcel lo que podríamos utilizar para este fin, no recomienda almacenar en el almacenamiento persistente.
Así que lo que sobra es una serialización de objetos simple - afortunadamente el SDK de Android tiene implementación de las clases ObjectInputStream y ObjectOutputStream con todos los inconvenientes y beneficios, como también lo haríamos en un mundo Java no androide, un simple:
ObjectOutputStream.writeObject(yourPojo)
haría la magia para nosotros, (recuerde implementar la interfaz de marcador Serializable)
Además, es posible que desee buscar en las siguientes API de Context - ContextWrapper - Activity, que son muy útiles para almacenar en caché los datos locales (como imágenes), etc.
.getCacheDir()
.getDir()
.openFileInput()
.openFileOutput()
hacking feliz :)