Guardar matriz de objetos personalizados en estado de instancia
Tengo una List<CustomObject>
(donde CustomObject
viene de una biblioteca externa – no puedo hacer cambios en ella). Quiero guardar esto en onSaveInstanceState(Bundle)
, pero no puedo hacerlo. Estas son las opciones que he probado:
outState.putSerializable(KEY, (ArrayList<CustomObject>) myList); // because myList is instantiated as an ArrayList outState.putSerializable(KEY, myList.toArray());
Ambas opciones funcionan cuando se cambia de orientación en el teléfono (sí, onSaveInstanceState
se llama al cambiar de orientación – Comprobé logcat). Sin embargo, cuando la actividad actual intenta iniciar otra (con startActivity(Intent)
), Android detiene la actividad actual y llama a onSaveInstanceState()
nuevo. Esta vez, falla, por alguna razón desconocida para mí. Lo peor es que onSaveInstanceState()
ejecuta correctamente. La traza de pila impresa no apunta a ninguno de mi código:
- Leer / escribir un objeto en un archivo
- ¿Cómo puedo serializar un objeto y guardarlo en un archivo de Android?
- ¿Pasar el objeto GoogleApiClient a otra actividad?
- Restlet en Android - Problemas con la serialización
- Guardar el estado de la instancia de ListView personalizado?
E/AndroidRuntime(23898): java.lang.RuntimeException: Parcel: unable to marshal value my.custom.Object@5e07e43b E/AndroidRuntime(23898): at android.os.Parcel.writeValue(Parcel.java:1087) E/AndroidRuntime(23898): at android.os.Parcel.writeArray(Parcel.java:519) E/AndroidRuntime(23898): at android.os.Parcel.writeValue(Parcel.java:1072) E/AndroidRuntime(23898): at android.os.Parcel.writeMapInternal(Parcel.java:469) E/AndroidRuntime(23898): at android.os.Bundle.writeToParcel(Bundle.java:1445) E/AndroidRuntime(23898): at android.os.Parcel.writeBundle(Parcel.java:483) E/AndroidRuntime(23898): at android.app.ActivityManagerProxy.activityPaused(ActivityManagerNative.java:1427) E/AndroidRuntime(23898): at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:3106) E/AndroidRuntime(23898): at android.app.ActivityThread.access$2400(ActivityThread.java:119) E/AndroidRuntime(23898): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1870) E/AndroidRuntime(23898): at android.os.Handler.dispatchMessage(Handler.java:99) E/AndroidRuntime(23898): at android.os.Looper.loop(Looper.java:123) E/AndroidRuntime(23898): at android.app.ActivityThread.main(ActivityThread.java:4363) E/AndroidRuntime(23898): at java.lang.reflect.Method.invokeNative(Native Method) E/AndroidRuntime(23898): at java.lang.reflect.Method.invoke(Method.java:521) E/AndroidRuntime(23898): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860) E/AndroidRuntime(23898): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) E/AndroidRuntime(23898): at dalvik.system.NativeStart.main(Native Method)
¿Hay alguna manera de almacenar objetos personalizados en el estado de la instancia?
- Archivo de serialización en Android
- BroadcastReceiver ClassNotFound Exception
- ¿Cuál es la mejor manera de diseñar un servidor GWT "independiente de la plataforma"?
- Gson serializar a LinkedTreeMap en lugar de mi Entidad
- ¿Puedo utilizar serialización con ofuscación?
- Ahorro de grandes arreglos cortos android
- Subclase serializable de clase padre no serializable
- ¿Cómo arreglar Unmarshalling código de tipo desconocido XXX en el desplazamiento YYY en Android?
Haga que su implemento Parcelable
y utilice:
outState.putParcelable(KEY, myList); onSaveInstanceState(outState);
También compruebe este tutorial.
EDITAR después del comentario de CommonsWare:
Si su CustomObject
no implementa Serializable
o Parcelable
intentaría envolverlo dentro de un objeto propio y añadir:
-
private void readObject(ObjectInputStream aStream) throws IOException, ClassNotFoundException { /*Your deserialization */ }
-
private void writeObject(ObjectOutputStream aStream) throws IOException { /*Your serialization */}
Haga que su List<CustomObject>
sea mantenida por un servicio y haga accesible a sus actividades a través del patrón de vinculación local.
No sólo no tiene que preocuparse de mantenerlo en su estado de instancia, sino que tiene un control un poco mejor sobre la vida de esos objetos en la memoria. La vida del estado de la instancia está controlada por Android; Cuánto tiempo un Service
mantiene en los objetos es controlado por usted. Particularmente si CustomObject
puede ser grande, o la lista puede ser larga, preferiría que tenga un mayor control sobre cuánto tiempo se consume esa RAM.
Si esto es principalmente para manejar los cambios de orientación, ¿puede Activity#onRetainNonConfigurationInstance()
hacer lo que desea?
Una actividad puede utilizar esta API para propagar el estado extenso de la antigua a la nueva instancia de actividad, de mapas de bits cargados, a las conexiones de red, a los threads de ejecución activa de manera uniforme. Tenga en cuenta que no debe propagar datos que puedan cambiar en función de la configuración, incluidos los datos cargados de recursos como cadenas, diseños o dibujos.
Esta API no le ayudará si intenta hacer más que persistir datos a través de los cambios de configuración.
Por lo que sé, SavedInstanceState
es para salvar la configuración de la interfaz de usuario de la actividad (como los widgets estándar de la interfaz de usuario de Android, por ejemplo, el campo de texto, se conservan automáticamente).
Si desea guardar un objeto personalizado entre diferentes relanzamientos de actividad (esto no se aplica al acabado iniciado por el usuario de una actividad haciendo clic en el botón Atrás, pero sí se aplica, por ejemplo, para cambios de orientación). Utilice el siguiente código para conservar un objeto:
// maintain a reference to the EchoServer object when the activity is recreated @Override public Object onRetainNonConfigurationInstance() { return <<your object of choice>>; }
Y en el método onCreate (Bundle savedInstanceState), puede recuperar el objeto:
// if there is a saved instance state, restore the state if (savedInstanceState != null) { <<yourObject>> = (<<your object's class) getLastNonConfigurationInstance();
¿Por qué no sólo guardar el objeto en la tarjeta SD? Puedes ver un ejemplo de cómo uso esto en mi blog >> http://androidworkz.com/2010/07/06/source-code-imageview-flipper-sd-card-scanner/
public void saveArray(String filename, String[] output_field) { try { FileOutputStream fos = new FileOutputStream(filename); GZIPOutputStream gzos = new GZIPOutputStream(fos); ObjectOutputStream out = new ObjectOutputStream(gzos); out.writeObject(output_field); out.flush(); out.close(); } catch (IOException e) { e.getStackTrace(); } } public String[] loadArray(String filename) { try { FileInputStream fis = new FileInputStream(filename); GZIPInputStream gzis = new GZIPInputStream(fis); ObjectInputStream in = new ObjectInputStream(gzis); String[] read_field = (String[])in.readObject(); in.close(); return read_field; } catch (Exception e) { e.getStackTrace(); } return null; }
- La biblioteca de Android no lanza sus recursos a otros proyectos
- ParseInstaller.getCurrentInstallation (). SaveInBackground () está congelando mi aplicación