Cómo utilizar el ejemplo de onSavedInstanceState por favor

110

Estoy confundido cuando se trata de salvar un estado. Entonces sé que onSaveInstanceState(Bundle)se llama cuando la actividad está a punto de ser destruida. Pero, ¿cómo almacena su información en él y la devuelve a su estado original onCreate(Bundle savedInstanceState)? No entiendo cómo este paquete restaurará la información. Sería útil que alguien pudiera dar un ejemplo. La guía para desarrolladores no explica bien esto.

public class Conversation extends Activity {
    private ProgressDialog progDialog;
    int typeBar;
    TextView text1;
    EditText edit;
    Button respond;
    private String name;
    private String textAtView;
    private String savedName;

    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);

        setContentView(R.layout.dorothydialog);
        text1 = (TextView)findViewById(R.id.dialog);
        edit = (EditText)findViewById(R.id.repsond);
        respond = (Button)findViewById(R.id.button01);

        if(savedInstanceState != null){
            savedInstanceState.get(savedName);
            text1.setText(savedName);
        }
        else{
            text1.setText("Hello! What is your name?");
            respond.setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View v) {
                    name = edit.getText().toString();
                    text1.setText("Nice to meet you "+ name);
                }   
            });
        }
    }

    @Override
    public void onSaveInstanceState(Bundle outState){
        super.onSaveInstanceState(outState);
        outState.putString(savedName, name);
    }
}
tj walker
fuente
text1.setText (SavedInstanceState.getString (SavedName));
Spidy
@Spidy ¿Qué pasa con onBackpressed? ¿Cómo reaccionaría a esto con el paquete?
tj walker
No lo harías. Cuando el usuario presiona el botón Atrás. La actividad se mata. Utilice una base de datos para el almacenamiento permanente de datos. Utilice el paquete para devolver una aplicación reiniciada a su estado anterior.
Spidy

Respuestas:

198

El Bundlees un contenedor de toda la información que desea guardar. Utiliza las funciones put * para insertar datos en él. Aquí hay una breve lista (hay más) de funciones de colocación que puede usar para almacenar datos en Bundle.

putString
putBoolean
putByte
putChar
putFloat
putLong
putShort
putParcelable (used for objects but they must implement Parcelable)

En su onCreatefunción, esto Bundlese devuelve al programa. La mejor forma de comprobar si la aplicación se está recargando o iniciando por primera vez es:

if (savedInstanceState != null) {
    // Then the application is being reloaded
}

Para recuperar los datos, use las funciones get * como las funciones put *. Los datos se almacenan como un par nombre-valor. Esto es como un mapa de hash. Usted proporciona una clave y el valor, luego, cuando desea recuperar el valor, le da la clave y la función obtiene el valor. He aquí un breve ejemplo.

@Override
public void onSaveInstanceState(Bundle outState) {
   outState.putString("message", "This is my message to be reloaded");
   super.onSaveInstanceState(outState);
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (savedInstanceState != null) {
        String message = savedInstanceState.getString("message");
        Toast.makeText(this, message, Toast.LENGTH_LONG).show();
    }
}

Su mensaje guardado se enviará a la pantalla. Espero que esto ayude.

Spidy
fuente
14
Se llama a onSaveInstanceState () antes de que se pause su actividad. Por lo tanto, cualquier información que necesite después de que se destruya potencialmente se puede recuperar del paquete guardado
Diederik
@ Spidy Awesome! ¡Realmente me hiciste entender todo sobre un paquete! así que supongo que outState se devuelve al paquete SavedInstanceState. ¿Correcto?
tj walker
Sí. El paquete outState se devuelve como el paquete InstanceState guardado
Spidy
1
@tj walker - Otro gran recurso son los libros de referencia técnica. Pro Android 3 es un recurso barato pero extenso que puede obtener en Amazon
Spidy
@Spidy Publiqué mi código de actividad arriba para que lo veas. Tal vez puedas hacerme saber si estoy salvando bien mi estado, como sugieres.
tj walker
34

Una nota importante que todos los nuevos desarrolladores de Android deben saber es que Android conservará automáticamente cualquier información en los widgets (TextView, botones, etc.) siempre que les asigne una ID. Eso significa que la mayor parte del estado de la interfaz de usuario se resuelve sin problemas. Solo cuando necesita almacenar otros datos, esto se convierte en un problema.

Desde Android Docs :

El único trabajo que debe realizar es proporcionar una identificación única (con el atributo android: id) para cada widget en el que desea guardar su estado. Si un widget no tiene una ID, no puede guardar su estado

Keith Adler
fuente
1
Bueno, ¿es eso realmente cierto? Porque tengo una actividad con un botón de visualización de texto y edición de texto. Si la aplicación se destruye o se mata, todo vuelve a su estado original. En mi aplicación, los textos de textView cambian cada vez que el usuario hace clic en el botón.
tj walker
¿La documentación es inexacta? Nunca he tenido una Vista que guarde su propia información. En mi opinión, su mejor opción es guardar toda su información usted mismo.
Spidy
2
Si su objetivo es guardar información onSaveInstanceState NO es el lugar para hacerlo. Esto se debe a que no hay garantía de que se llame (consulte los documentos). En su lugar, debería escribir en una base de datos, SharedPreferences, etc. Sí, esta información es precisa. La mejor manera de probar si su interfaz de usuario persiste de esta manera es girar la pantalla a medida que cambia de orientación, vuelva a ejecutar su onCreate y use el paquete para restaurar el estado.
Keith Adler
@Nissan Fan, ¿puedes dar un ejemplo como lo hizo Spidy? ¿Con las preferencias compartidas y todo? Gracias
tj walker
Los mejores ejemplos, francamente, provienen de la documentación. developer.android.com/guide/topics/data/data-storage.html#pref
Keith Adler
6

Una buena información: no es necesario verificar si el objeto Bundle es nulo en el método onCreate (). Utilice el método onRestoreInstanceState (), que el sistema llama después del método onStart (). El sistema llama a onRestoreInstanceState () solo si hay un estado guardado para restaurar, por lo que no es necesario verificar si el paquete es nulo

Diego Souza
fuente
5

Almacenar información:

static final String PLAYER_SCORE = "playerScore";
static final String PLAYER_LEVEL = "playerLevel";

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    // Save the user's current game state
    savedInstanceState.putInt(PLAYER_SCORE, mCurrentScore);
    savedInstanceState.putInt(PLAYER_LEVEL, mCurrentLevel);

// Always call the superclass so it can save the view hierarchy state
super.onSaveInstanceState(savedInstanceState);
}

Si no desea restaurar la información en su método onCreate:

Estos son los ejemplos: Recreación de una actividad

En lugar de restaurar el estado durante onCreate (), puede optar por implementar onRestoreInstanceState (), que el sistema llama después del método onStart (). El sistema llama a onRestoreInstanceState () solo si hay un estado guardado para restaurar, por lo que no es necesario verificar si el paquete es nulo

public void onRestoreInstanceState(Bundle savedInstanceState) {
// Always call the superclass so it can restore the view hierarchy
super.onRestoreInstanceState(savedInstanceState);

// Restore state members from saved instance
mCurrentScore = savedInstanceState.getInt(PLAYER_SCORE);
mCurrentLevel = savedInstanceState.getInt(PLAYER_LEVEL);
}
Klatschen
fuente
0

Básicamente, onSaveInstanceState (Bundle outBundle) le dará un paquete. Cuando mires la clase Bundle, verás que puedes poner muchas cosas diferentes dentro de ella. En la siguiente llamada de onCreate (), solo obtiene ese Bundle como argumento. Luego, puede volver a leer sus valores y restaurar su actividad.

Digamos que tiene una actividad con un EditText. El usuario escribió un texto en su interior. Después de eso, el sistema llama a su onSaveInstanceState (). Usted lee el texto de EditText y lo escribe en el Bundle a través de Bundle.putString ("edit_text_value", theValue).

Ahora se llama a onCreate. Comprueba si el paquete suministrado no es nulo. Si ese es el caso, puede restaurar su valor a través de Bundle.getString ("edit_text_value") y volver a colocarlo en su EditText.


fuente
0

Esto es para información adicional.

Imagina este escenario

  1. ActivityA iniciar ActivityB.
  2. ActivityB lanza un nuevo ActivityAPrime por

    Intent intent = new Intent(getApplicationContext(), ActivityA.class);
    startActivity(intent);
  3. ActivityAPrime no tiene ninguna relación con ActivityA.
    En este caso, el Bundle en ActivityAPrime.onCreate () será nulo.

Si ActivityA y ActivityAPrime deberían ser la misma actividad en lugar de actividades diferentes, ActivityB debería llamar a finish () en lugar de usar startActivity ().

conocido
fuente
solo para aclarar, en su ejemplo, ¿ActivityA == ActivityA instancia 1 y ActivityAPrime == ActivityA instancia 2? también, cuando dices, "ActivityB debería llamar a finish () que usar startActivity ()". ¿Quieres decir: (1) AcitivityB debería llamar a finish () y luego usar startActivity () después (2) o ActivityB debería llamar a finish () en lugar de usar startActivity () en absoluto? Si se refería a la opción 2, ¿cómo sugeriría que alguien reinicie la misma actividad Una instancia 1 para que pueda cargar los datos que la actividad contenía antes de ser destruida / finalizada? Gracias
cjayem13
ActivityA y ActivityAPrime son de la misma clase pero instancias diferentes. En este escenario, ActivityA aún no ha terminado su negocio, en medio de él, creó e inició ActivityB, por lo que cuando ActivityB finalice, ActivityA debería continuar con el resto de su negocio. Es incorrecto llamar a startActivity en este caso y esperar que ActivityA y ActiviyAPrime sean la misma instancia. por lo que no deberíamos reiniciar ActivityA, solo terminar ActivityB y dejar que ActivityA reanude su funcionamiento ...
ken
0

Si los datos no se cargan desde, savedInstanceStateutilice el siguiente código.
El problema es que la llamada a la URL no se completa por completo, así que verifique si los datos están cargados y luego mostrar el valor de instanceState.

//suppose data is not Loaded to savedInstanceState at 1st swipe
if (savedInstanceState == null && !mAlreadyLoaded){
    mAlreadyLoaded = true;
    GetStoryData();//Url Call
} else {
    if (listArray != null) {  //Data Array From JsonArray(ListArray)
        System.out.println("LocalData  " + listArray);
        view.findViewById(R.id.progressBar).setVisibility(View.GONE);
    }else{
        GetStoryData();//Url Call
    }
}
Mathan Chinna
fuente