2010-10-12 6 views
51

yo estaba buscando en el camino Android maneja cambio de orientación para mi aplicación (descubrí que se reinicia el mainactivity sobre el cambio de orientación. He visto que se puede reemplazar el método¿Cómo guardar el estado durante el cambio de orientación en Android si el estado está hecho de mis clases?

protected void onSaveInstanceState(Bundle outState) 

Para guardar cosas, entonces tiene the in onStart. El problema es que tengo mi vista con objetos personalizados y una vista de lista usando un adaptador personalizado. Todo está en una ArrayList de estos objetos, ¡pero he notado que no puedes poner objetos arbitrarios en el paquete! Entonces, ¿cómo puedo guardar el estado?

Respuesta

36

EDITAR: En las versiones más nuevas de Android y con la biblioteca de compatibilidad, retained fragments suelen ser la mejor manera de manejar mantener datos costosos para recrear con vida a través de la destrucción/creación de la actividad. Y como señaló Dianne, conservar los datos de no configuración era para optimizar cosas como la generación de miniaturas que son fáciles de guardar por motivos de rendimiento pero no críticas para el funcionamiento de su actividad si necesitan rehacerse; no es un sustituto para guardar y restaurar correctamente el estado de la actividad.

Pero cuando yo primero respondí esto en 2010:
Si desea conservar sus propios datos (no del estado de vista), en realidad se puede pasar un objeto arbitrario específicamente para la orientación cambia al utilizar onRetainNonConfigurationInstance(). Ver this Android Developers blog post. Solo tenga cuidado de no colocar ninguna vista u otras referencias al contexto/actividad de prerrotación en el objeto que pase, o evitará que esos objetos sean basura y eventualmente se quede sin memoria (esto se llama context leak) .

+7

Tenga en cuenta que onRetainNonConfigurationInstance() debe * * Sólo puede utilizar como una optimización. Su aplicación debería funcionar incluso si esto no ocurre ... porque no hay * garantía * de que así sea y, de hecho, muchas situaciones en las que definitivamente no se llamará. Primero debe hacer que su aplicación funcione correctamente a través del mecanismo de estado completo guardado, y solo implemente este método como una optimización. – hackbod

+0

El enlace de arriba no está disponible. ¿Puedes darme otro enlace? – Debopam

+2

Esos métodos están en desuso ... –

16

Primero, debe determinar qué es realmente el "estado" en su aplicación. No ha dicho lo que está haciendo en realidad, pero déjeme suponer que ArrayList de objetos es el estado con el que está trabajando el usuario.

En segundo lugar, decida cuál es realmente el ciclo de vida de este estado. ¿Está realmente vinculado a esa actividad? ¿O el usuario no debería perderlo si la batería baja, el dispositivo se apaga y luego vuelve a su aplicación? Si el primero, onSaveInstanceState() es correcto; en este último caso, deseará guardar en el almacenamiento permanente en onPause().

Para onSaveInstanceState() con objetos personalizados, la clave es implementar la interfaz Parcelable. Esto implica implementar los métodos en Parcelable, así como crear un objeto CREATOR estático en su clase. Aquí está el código para una clase parcelable sencilla típica:

https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/content/ComponentName.java

Las funciones principales son la implementación parcelable:

https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/content/ComponentName.java#317

y la clase estática CREADOR:

https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/content/ComponentName.java#355

(El estático writeToParcel() y readFromParcel() son solo comodidades que se hicieron para esa clase y no son obligatorias.)

Ahora que tiene eso, se puede poner toda su ArrayList de objetos en el archivo de estado guardado con Bundle.putParcelableArrayList:

http://developer.android.com/reference/android/os/Bundle.html#putParcelableArrayList(java.lang.String, java.util.ArrayList)

En Activity.onCreate(), comprobar para ver si tiene un savedState Bundle, y si intente recuperar ArrayList de eso y utilícelo si lo encuentra, creando un nuevo adaptador y vista de lista para la nueva actividad que se usa para mostrarlo.

134

¿Ha intentado utilizar: su trabajo alrededor,

<activity name= ".YourActivity" android:configChanges="orientation|screenSize"/> 

en el archivo de manifiesto?

No funciona de manera predeterminada porque, cuando cambie la orientación, se volverá a llamar al onCreate y se volverá a dibujar su vista.

Si escribe este parámetro sin necesidad de manejarlo en Activity, el framework se encargará del resto de las cosas. Retendrá el estado de la pantalla o el diseño si se cambia la orientación.

NOTA Si está utilizando un diseño diferente para el modo horizontal, al agregar estos parámetros, no se llamará al diseño para el modo horizontal.

Other way y Another way

+7

+1 para screenSize! Lo solucioné para mí :-) – Abdo

+3

Muchas gracias, ¡esto me ayudará mucho! – Marius

+9

¿Por qué no es así como funciona de manera predeterminada? ¿Quién quiere que se pierdan sus datos en la rotación? – CodeSlinger512

3

pero me he dado cuenta que no se puede poner objetos arbitrarios en el paquete!

Primero haga sus objetos personalizados Parcelable.
Luego puede ponerlos en un paquete.

Todo está en un ArrayList de estos objetos

Puede utilizar putParcelableArrayList método en el paquete para almacenar un ArrayList de objetos a medida "parcelable".

3

escribe tus objetos en Cuerdas JSON usando Google's Gson, luego guárdalos como una Cadena. Entonces, construirlos de vuelta de los salvados JSON cuerdas cuando la reconstrucción de la Actividad/Fragmento

import com.google.gson.Gson; 

public class MyClass { 
    private int a; 
    private String s; 
    private OtherSerializableClass other; 
    private List<String> list; 

    public String toJson() { 
     return new Gson().toJson(this); 
    } 

    public static ChatAPI_MessagesArray fromJson(String json){ 
     return new Gson().fromJson(json, YourClass.class); 
    } 

    // Getters 
    ... 

    // Setters 
    ... 
} 
+0

Tengo muchos diseños, textviews y botones que se crean mediante programación en mainactivity. ¿La solución que proporcionó aquí cubre mi caso o debo utilizar un enfoque diferente? Gracias – Eftekhari

Cuestiones relacionadas