Guardar el estado de actividad de Android usando Guardar estado de instancia


He estado trabajando en la plataforma Android SDK, y no está claro cómo guardar el estado de una aplicación. Así que dado este menor re-herramientas de la 'Hola, Android' ejemplo:

package com.android.hello;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class HelloAndroid extends Activity {

  private TextView mTextView = null;

  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    mTextView = new TextView(this);

    if (savedInstanceState == null) {
       mTextView.setText("Welcome to HelloAndroid!");
    } else {
       mTextView.setText("Welcome back.");
    }

    setContentView(mTextView);
  }
}

Pensé que sería suficiente para el caso más simple, pero siempre responde con el primer mensaje, no importa cómo navegue lejos de la aplicación.

Estoy seguro de que la solución es tan simple como anular onPause o algo así, pero he estado husmeando en la documentación durante 30 minutos más o menos y no he encontrado nada obvio.

Author: Taryn, 2008-09-30

27 answers

Necesita anular onSaveInstanceState(Bundle savedInstanceState) y escribir los valores de estado de la aplicación que desea cambiar al parámetro Bundle de la siguiente manera:

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
  super.onSaveInstanceState(savedInstanceState);
  // Save UI state changes to the savedInstanceState.
  // This bundle will be passed to onCreate if the process is
  // killed and restarted.
  savedInstanceState.putBoolean("MyBoolean", true);
  savedInstanceState.putDouble("myDouble", 1.9);
  savedInstanceState.putInt("MyInt", 1);
  savedInstanceState.putString("MyString", "Welcome back to Android");
  // etc.
}

El Paquete es esencialmente una forma de almacenar un mapa NVP ("Par Nombre-Valor"), y se pasará a onCreate() y también a onRestoreInstanceState() donde extraerás los valores de la siguiente manera:

@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
  super.onRestoreInstanceState(savedInstanceState);
  // Restore UI state from the savedInstanceState.
  // This bundle has also been passed to onCreate.
  boolean myBoolean = savedInstanceState.getBoolean("MyBoolean");
  double myDouble = savedInstanceState.getDouble("myDouble");
  int myInt = savedInstanceState.getInt("MyInt");
  String myString = savedInstanceState.getString("MyString");
}

Normalmente utilizaría esta técnica para almacenar valores de instancia para su aplicación (selecciones, texto no guardado, etc.).).

 2316
Author: Reto Meier,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-07 10:11:08

El savedInstanceState es solo para guardar el estado asociado con una instancia actual de una Actividad, por ejemplo, navegación actual o información de selección, de modo que si Android destruye y recrea una Actividad, puede volver a ser como era antes. Consulte la documentación de onCreate y onSaveInstanceState

Para un estado más duradero, considere usar una base de datos SQLite, un archivo o preferencias. Ver Guardar Estado persistente.

 385
Author: Dave L.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-13 00:24:16

Tenga en cuenta que es NO seguro de usar onSaveInstanceState y onRestoreInstanceState para datos persistentes, de acuerdo con la documentación sobre los estados de actividad en http://developer.android.com/reference/android/app/Activity.html .

El documento indica (en la sección 'Ciclo de vida de la actividad'):

Tenga en cuenta que es importante guardar datos persistentes en onPause() en su lugar de onSaveInstanceState(Bundle) porque el más tarde no es parte de la callbacks del ciclo de vida, por lo que no será llamado en cada situación como se describe en su documentación.

En otras palabras, ponga su código de guardar/restaurar para datos persistentes en onPause() y onResume()!

EDITAR : Para mayor aclaración, aquí está la documentación onSaveInstanceState():

Este método se llama antes de que una actividad pueda ser eliminada de modo que cuando vuelve en algún momento en el futuro puede restaurar su estado. Para ejemplo, si la actividad B se lanza delante de la actividad A, y en algunos punto actividad A es asesinado para reclamar recursos, actividad A tendrá una oportunidad de guardar el estado actual de su interfaz de usuario a través de esta método de modo que cuando el usuario vuelve a la actividad A, el estado de la la interfaz de usuario se puede restaurar a través de onCreate(Bundle) o onRestoreInstanceState(Bundle).

 373
Author: Steve Moseley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-24 23:04:27

Mi colega escribió un artículo explicando el Estado de la aplicación en dispositivos Android, incluyendo explicaciones sobre el Ciclo de Vida de la Actividad y la Información de Estado, Cómo almacenar Información de Estado y guardar en Estado Bundle y SharedPreferences y echa un vistazo aquí .

El artículo cubre tres enfoques:

Almacene los datos de control de la interfaz de usuario/variable local durante la vida útil de la aplicación (es decir, temporalmente) utilizando el Paquete de Estado de la instancia

[Code sample – Store State in State Bundle]
@Override
public void onSaveInstanceState(Bundle savedInstanceState) 
{
  // Store UI state to the savedInstanceState.
  // This bundle will be passed to onCreate on next call.  EditText txtName = (EditText)findViewById(R.id.txtName);
  String strName = txtName.getText().toString();

  EditText txtEmail = (EditText)findViewById(R.id.txtEmail);
  String strEmail = txtEmail.getText().toString();

  CheckBox chkTandC = (CheckBox)findViewById(R.id.chkTandC);
  boolean blnTandC = chkTandC.isChecked();

  savedInstanceState.putString(“Name”, strName);
  savedInstanceState.putString(“Email”, strEmail);
  savedInstanceState.putBoolean(“TandC”, blnTandC);

  super.onSaveInstanceState(savedInstanceState);
}

Almacenar datos de control de varible/UI locales entre aplicaciones instancias (es decir, permanentemente) usando Preferencias compartidas

[Code sample – Store State in SharedPreferences]
@Override
protected void onPause() 
{
  super.onPause();

  // Store values between instances here
  SharedPreferences preferences = getPreferences(MODE_PRIVATE);
  SharedPreferences.Editor editor = preferences.edit();  // Put the values from the UI
  EditText txtName = (EditText)findViewById(R.id.txtName);
  String strName = txtName.getText().toString();

  EditText txtEmail = (EditText)findViewById(R.id.txtEmail);
  String strEmail = txtEmail.getText().toString();

  CheckBox chkTandC = (CheckBox)findViewById(R.id.chkTandC);
  boolean blnTandC = chkTandC.isChecked();

  editor.putString(“Name”, strName); // value to store
  editor.putString(“Email”, strEmail); // value to store
  editor.putBoolean(“TandC”, blnTandC); // value to store    
  // Commit to storage
  editor.commit();
}

Mantener las instancias de objeto activas en la memoria entre actividades dentro de la vida útil de la aplicación utilizando la Instancia no Configurada conservada

[Code sample – store object instance]
private cMyClassType moInstanceOfAClass;// Store the instance of an object
@Override
public Object onRetainNonConfigurationInstance() 
{
  if (moInstanceOfAClass != null) // Check that the object exists
      return(moInstanceOfAClass);
  return super.onRetainNonConfigurationInstance();
}
 174
Author: Martin Belcher - Eigo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-18 09:58:31

Este es un clásico 'gotcha' de desarrollo de Android. Hay dos cuestiones aquí:

  • Hay un sutil error en el marco de Android que complica enormemente la administración de la pila de aplicaciones durante el desarrollo, al menos en versiones heredadas (no estoy completamente seguro de si/cuándo/cómo se arregló). Voy a discutir este error a continuación.
  • La forma 'normal' o prevista de manejar este problema es, en sí misma, bastante complicada con la dualidad de onPause / onResume y onSaveInstanceState/onRestoreInstanceState

Navegando a través de todos estos hilos, sospecho que la mayor parte del tiempo los desarrolladores están hablando de estos dos temas diferentes simultáneamente ... de ahí toda la confusión y los informes de "esto no funciona para mí".

Primero, para aclarar el comportamiento 'pretendido': onaveinstance y onRestoreInstance son frágiles y solo para estados transitorios. El uso previsto (afaict) es manejar la recreación de la actividad cuando se gira el teléfono (cambio de orientación). En otras palabras, el uso previsto es cuando su Actividad sigue siendo lógicamente 'en la parte superior', pero todavía debe ser reinstanciado por el sistema. El Paquete guardado no se conserva fuera del proceso/memory/gc, por lo que realmente no puede confiar en esto si su actividad pasa a segundo plano. Sí, tal vez la memoria de su Actividad sobrevivirá a su viaje al fondo y escapará GC, pero esto no es confiable (ni es predecible).

Así que si usted tiene un escenario donde hay 'progreso del usuario' significativo o estado que debe persistir entre 'lanzamientos' de su aplicación, la guía es usar onPause y onResume. Debe elegir y preparar una tienda persistente usted mismo.

PERO - hay un error muy confuso que complica todo esto. Los detalles están aquí:

Http://code.google.com/p/android/issues/detail?id=2373

Http://code.google.com/p/android/issues/detail?id=5277

Básicamente, si su solicitud se inicia con la bandera singleTask, y luego se inicia desde la pantalla de inicio o el menú del lanzador, a continuación, esa invocación posterior creará una NUEVA tarea ... tendrás efectivamente dos instancias diferentes de tu aplicación habitando la misma pila ... lo que se pone muy extraño muy rápido. Esto parece suceder cuando lanzas tu aplicación durante el desarrollo (es decir, desde Eclipse o Intellij), por lo que los desarrolladores se encuentran con esto mucho. Pero también a través de algunos de los mecanismos de actualización de la app store (por lo que afecta sus usuarios también).

Luché a través de estos hilos durante horas antes de darme cuenta de que mi problema principal era este error, no el comportamiento del marco previsto. Una gran valoración crítica y solución (ACTUALIZACIÓN: ver a continuación) parece ser del usuario @kaciula en esta respuesta:

Inicio comportamiento de las teclas pulsadas

ACTUALIZACIÓN Junio 2013 : Meses después, finalmente he encontrado la solución 'correcta'. No necesita administrar ningún indicador de startedApp con estado usted mismo, puede detecte esto desde el marco y pague la fianza apropiadamente. Uso esto cerca del comienzo de mi actividad de lanzamiento.onCreate:

if (!isTaskRoot()) {
    Intent intent = getIntent();
    String action = intent.getAction();
    if (intent.hasCategory(Intent.CATEGORY_LAUNCHER) && action != null && action.equals(Intent.ACTION_MAIN)) {
        finish();
        return;
    }
}
 129
Author: Mike Repass,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:26:34

onSaveInstanceState se llama cuando el sistema necesita memoria y mata una aplicación. No se llama cuando el usuario cierra la aplicación. Así que creo que el estado de la aplicación también debe guardarse en onPause Debe guardarse en algún almacenamiento persistente como Preferences o Sqlite

 70
Author: Fedor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-20 14:07:53

Ambos métodos son útiles y válidos y ambos son los más adecuados para diferentes escenarios:

  1. El usuario termina la aplicación y la vuelve a abrir en una fecha posterior, pero la aplicación necesita volver a cargar los datos de la última sesión-esto requiere un enfoque de almacenamiento persistente, como el uso de SQLite.
  2. El usuario cambia la aplicación y luego vuelve a la original y quiere continuar donde lo dejó: guardar y restaurar los datos del paquete (como los datos del estado de la aplicación) en onSaveInstanceState() y onRestoreInstanceState() suele ser adecuado.

Si guarda los datos de estado de manera persistente, se pueden recargar en un onResume() o onCreate() (o en realidad en cualquier llamada de ciclo de vida). Este puede o no ser el comportamiento deseado. Si lo almacena en un paquete en un InstanceState, entonces es transitorio y solo es adecuado para almacenar datos para su uso en la misma 'sesión' de usuario (uso el término sesión libremente), pero no entre 'sesiones'.

No es que un enfoque sea mejor que el otro, como todo, es solo es importante entender qué comportamiento requiere y seleccionar el enfoque más adecuado.

 59
Author: David,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-12 23:34:47

Estado de ahorro es un kludge en el mejor de los casos en lo que a mí respecta. Si necesita guardar datos persistentes, simplemente use una base de datos SQLite. Android lo hace SOOO tranquilo.

Algo como esto:

import java.util.Date;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class dataHelper {

    private static final String DATABASE_NAME = "autoMate.db";
    private static final int DATABASE_VERSION = 1;

    private Context context;
    private SQLiteDatabase db;
    private OpenHelper oh ;

    public dataHelper(Context context) {
        this.context = context;
        this.oh = new OpenHelper(this.context);
        this.db = oh.getWritableDatabase();
    }

    public void close()
    {
        db.close();
        oh.close();
        db = null;
        oh = null;
        SQLiteDatabase.releaseMemory();
    }


    public void setCode(String codeName, Object codeValue, String codeDataType)
    {
        Cursor codeRow = db.rawQuery("SELECT * FROM code WHERE codeName = '"+  codeName + "'", null);
        String cv = "" ;

        if (codeDataType.toLowerCase().trim().equals("long") == true)
        {
            cv = String.valueOf(codeValue);
        }
        else if (codeDataType.toLowerCase().trim().equals("int") == true)
        {
            cv = String.valueOf(codeValue);
        }
        else if (codeDataType.toLowerCase().trim().equals("date") == true)
        {
            cv = String.valueOf(((Date)codeValue).getTime());
        }
        else if (codeDataType.toLowerCase().trim().equals("boolean") == true)
        {
            String.valueOf(codeValue);
        }
        else
        {
            cv = String.valueOf(codeValue);
        }

        if(codeRow.getCount() > 0) //exists-- update
        {
            db.execSQL("update code set codeValue = '" + cv +
                "' where codeName = '" + codeName + "'");
        }
        else // does not exist, insert
        {
            db.execSQL("INSERT INTO code (codeName, codeValue, codeDataType) VALUES(" +
                    "'" + codeName + "'," +
                    "'" + cv + "'," +
                    "'" + codeDataType + "')" );
        }
    }

    public Object getCode(String codeName, Object defaultValue)
    {
        //Check to see if it already exists
        String codeValue = "";
        String codeDataType = "";
        boolean found = false;
        Cursor codeRow  = db.rawQuery("SELECT * FROM code WHERE codeName = '"+  codeName + "'", null);
        if (codeRow.moveToFirst())
        {
            codeValue = codeRow.getString(codeRow.getColumnIndex("codeValue"));
            codeDataType = codeRow.getString(codeRow.getColumnIndex("codeDataType"));
            found = true;
        }

        if (found == false)
        {
            return defaultValue;
        }
        else if (codeDataType.toLowerCase().trim().equals("long") == true)
        {
            if (codeValue.equals("") == true)
            {
                return (long)0;
            }
            return Long.parseLong(codeValue);
        }
        else if (codeDataType.toLowerCase().trim().equals("int") == true)
        {
            if (codeValue.equals("") == true)
            {
                return (int)0;
            }
            return Integer.parseInt(codeValue);
        }
        else if (codeDataType.toLowerCase().trim().equals("date") == true)
        {
            if (codeValue.equals("") == true)
            {
                return null;
            }
            return new Date(Long.parseLong(codeValue));
        }
        else if (codeDataType.toLowerCase().trim().equals("boolean") == true)
        {
            if (codeValue.equals("") == true)
            {
                return false;
            }
            return Boolean.parseBoolean(codeValue);
        }
        else
        {
            return (String)codeValue;
        }
    }


    private static class OpenHelper extends SQLiteOpenHelper {

        OpenHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL("CREATE TABLE IF  NOT EXISTS code" +
            "(id INTEGER PRIMARY KEY, codeName TEXT, codeValue TEXT, codeDataType TEXT)");
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        }
    }
}

Una simple llamada después de eso

dataHelper dh = new dataHelper(getBaseContext());
String status = (String) dh.getCode("appState", "safetyDisabled");
Date serviceStart = (Date) dh.getCode("serviceStartTime", null);
dh.close();
dh = null;
 50
Author: Mike A.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-21 22:08:12

Creo que encontré la respuesta. Permítanme decir lo que he hecho en palabras simples:

Supongamos que tengo dos actividades, activity1 y activity2 y estoy navegando de activity1 a activity2 (he hecho algunos trabajos en activity2) y de nuevo vuelvo a la actividad 1 haciendo clic en un botón en activity1. Ahora en esta etapa quería volver a activity2 y quiero ver mi activity2 en la misma condición cuando me fui por última vez activity2.

Para el escenario anterior lo que he hecho es que en el manifiesto hice algunos cambios como este:

<activity android:name=".activity2"
          android:alwaysRetainTaskState="true"      
          android:launchMode="singleInstance">
</activity>

Y en la actividad1 en el evento de clic del botón he hecho así:

Intent intent = new Intent();
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
intent.setClassName(this,"com.mainscreen.activity2");
startActivity(intent);

Y en activity2 en el evento de clic en el botón he hecho así:

Intent intent=new Intent();
intent.setClassName(this,"com.mainscreen.activity1");
startActivity(intent);

Ahora lo que sucederá es que cualesquiera que sean los cambios que hayamos hecho en la actividad2 no se perderán, y podremos ver actividad2 en el mismo estado que dejamos anteriormente.

Creo que esta es la respuesta y esto funciona bien para mí. Corrígeme si me equivoco.

 49
Author: roy mathew,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-31 19:01:15

Recrear una actividad

Hay algunos escenarios en los que su actividad se destruye debido al comportamiento normal de la aplicación, como cuando el usuario presiona el botón Atrás o su actividad señala su propia destrucción llamando a finish(). El sistema también puede destruir su actividad si actualmente está detenida y no se ha utilizado en mucho tiempo o si la actividad en primer plano requiere más recursos, por lo que el sistema debe apagar los procesos en segundo plano para recuperar la memoria.

Cuando su activity se destruye porque el usuario presiona hacia atrás o el activity se termina por sí mismo, el concepto del sistema de esa instancia Activity se ha ido para siempre porque el comportamiento indica que la actividad ya no es necesaria. Sin embargo, si el sistema destruye la actividad debido a restricciones del sistema (en lugar del comportamiento normal de la aplicación), a pesar de que la instancia de Actividad real se ha ido, el sistema recuerda que existía de tal manera que si el usuario navega de nuevo a ella, el sistema crea una nueva instancia de la actividad usando un conjunto de datos guardados que describe el estado de la actividad cuando era destroyed. Los datos guardados que el sistema utiliza para restaurar el estado anterior se denominan "estado de instancia" y son una colección de pares clave-valor almacenados en un objeto Bundle.

Para guardar datos adicionales sobre el estado de la actividad, debe sobrescribir el método de devolución de llamada onaveinstancestate (). El sistema llama a este método cuando el usuario abandona su actividad y le pasa el objeto Bundle que se guardará en el evento que su actividad se destruye inesperadamente. Si el sistema debe recrear la instancia de actividad más tarde, pasa el mismo objeto Bundle a los métodos onRestoreInstanceState() y onCreate(). introduzca la descripción de la imagen aquí

A medida que el sistema comienza a detener su actividad, llama a onSaveInstanceState() (1) para que pueda especificar datos de estado adicionales que desea guardar en caso de que la instancia de Actividad deba ser recreada. Si la actividad es destruida y la misma instancia debe ser recreada, el sistema pasa los datos de estado definidos en (1) tanto al método onCreate() (2) como al método onRestoreInstanceState() (3).

Guarde Su Activity Estado

A medida que su actividad comienza a detenerse, el sistema llama a onSaveInstanceState() para que su actividad pueda guardar información de estado con una colección de pares clave-valor. La implementación predeterminada de este método guarda información sobre el estado de la jerarquía de vistas de la actividad, como el texto en un widget EditText o la posición de desplazamiento de un ListView.

Para guardar información de estado adicional para su actividad, debe implementar onSaveInstanceState() y agregar pares clave-valor al objeto Bundle. Por ejemplo:

  static final String STATE_SCORE = "playerScore";
  static final String STATE_LEVEL = "playerLevel";

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

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

Precaución: Siempre llame a la implementación de superclase de onSaveInstanceState() para que la implementación predeterminada pueda guardar el estado de la jerarquía de vistas.

Restaurar Su Activity Estado

Cuando su actividad se vuelve a crear después de que se destruyó previamente, puede recuperar su estado guardado del Paquete que el sistema pasa a su actividad. Tanto el onCreate() y onRestoreInstanceState() los métodos callback reciben el mismo Bundle que contiene la información de estado de la instancia.

Debido a que el método onCreate() se llama si el sistema está creando una nueva instancia de su actividad o recreando una anterior, debe verificar si el paquete de estado es null antes de intentar leerlo. Si es null, entonces el sistema está creando una nueva instancia de la actividad, en lugar de restaurar una anterior que fue destruida.

Por ejemplo, así es como puede restaurar algunos indique los datos en onCreate():

 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState); // Always call the superclass first

 // Check whether we're recreating a previously destroyed instance
 if (savedInstanceState != null) {
    // Restore value of members from saved state
    mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
    mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
 } else {
    // Probably initialize members with default values for a new instance
 }

 }

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(STATE_SCORE);
  mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
}
 37
Author: Ravi Vaghela,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-28 08:16:39

onSaveInstanceState() para datos transitorios (restaurados en onCreate()/onRestoreInstanceState()), onPause() para datos persistentes (restaurados en onResume()). Desde Android recursos técnicos:

Androidaveinstancestate () es llamado por Android si la Actividad está siendo detenida y puede ser eliminada antes de que se reanude! Esto significa que debe almacenar cualquier estado necesario para volver a inicializar a la misma condición cuando se reinicia la Actividad. Es la contraparte del método onCreate (), y de hecho el paquete savedInstanceState pasado a onCreate() es el mismo Paquete que construyes como outState en el método onaveinstancestate ().

OnPause() y onResume() son también métodos de cortesía. onPause () siempre se llama cuando la Actividad termina, incluso si lo iniciamos (con una llamada finish (), por ejemplo). Usaremos esto para guardar la nota actual en la base de datos. Una buena práctica es liberar cualquier recurso que pueda ser liberado durante una onPause (), así, para tomar menos recursos en estado pasivo.

 35
Author: Ixx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-17 21:29:07

Really onSaveInstance state callen cuando la Actividad pasa a segundo plano

Cita de los documentos: "el método onSaveInstanceState(Bundle) se llama antes de colocar la actividad en ese estado de fondo"

 31
Author: u-foka,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-20 14:08:10

Mientras tanto hago en general no más uso

Bundle savedInstanceState & Co

El ciclo en vivo es para la mayoría de las actividades demasiado complicado y no necesario. Y Google se declara, ni siquiera es confiable.

Mi manera es guardar cualquier cambio inmediatamente en las preferencias

 SharedPreferences p;
 p.edit().put(..).commit()

De alguna manera SharedPreferences funciona de manera similar a los paquetes. Y naturalmente y primero tales valores deben ser rojos de las preferencias.

En el caso de datos complejos, puede usar Sqlite en lugar de usar preferencia.

Al aplicar este concepto, la actividad simplemente continúa utilizando el último estado guardado, independientemente de si fue una apertura inicial con reinicios en el medio o una reapertura debido a la pila posterior.

 27
Author: stefan bachert,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-31 13:36:59

Para ayudar a reducir la repetición utilizo los siguientes interface y class para leer/escribir en un Bundle para guardar el estado de la instancia.


Primero, cree una interfaz que se utilizará para anotar sus variables de instancia:

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({
        ElementType.FIELD
})
public @interface SaveInstance {

}

Luego, cree una clase donde la reflexión se utilizará para guardar valores en el paquete:

import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.Log;

import java.io.Serializable;
import java.lang.reflect.Field;

/**
 * Save and load fields to/from a {@link Bundle}. All fields should be annotated with {@link
 * SaveInstance}.</p>
 */
public class Icicle {

    private static final String TAG = "Icicle";

    /**
     * Find all fields with the {@link SaveInstance} annotation and add them to the {@link Bundle}.
     *
     * @param outState
     *         The bundle from {@link Activity#onSaveInstanceState(Bundle)} or {@link
     *         Fragment#onSaveInstanceState(Bundle)}
     * @param classInstance
     *         The object to access the fields which have the {@link SaveInstance} annotation.
     * @see #load(Bundle, Object)
     */
    public static void save(Bundle outState, Object classInstance) {
        save(outState, classInstance, classInstance.getClass());
    }

    /**
     * Find all fields with the {@link SaveInstance} annotation and add them to the {@link Bundle}.
     *
     * @param outState
     *         The bundle from {@link Activity#onSaveInstanceState(Bundle)} or {@link
     *         Fragment#onSaveInstanceState(Bundle)}
     * @param classInstance
     *         The object to access the fields which have the {@link SaveInstance} annotation.
     * @param baseClass
     *         Base class, used to get all superclasses of the instance.
     * @see #load(Bundle, Object, Class)
     */
    public static void save(Bundle outState, Object classInstance, Class<?> baseClass) {
        if (outState == null) {
            return;
        }
        Class<?> clazz = classInstance.getClass();
        while (baseClass.isAssignableFrom(clazz)) {
            String className = clazz.getName();
            for (Field field : clazz.getDeclaredFields()) {
                if (field.isAnnotationPresent(SaveInstance.class)) {
                    field.setAccessible(true);
                    String key = className + "#" + field.getName();
                    try {
                        Object value = field.get(classInstance);
                        if (value instanceof Parcelable) {
                            outState.putParcelable(key, (Parcelable) value);
                        } else if (value instanceof Serializable) {
                            outState.putSerializable(key, (Serializable) value);
                        }
                    } catch (Throwable t) {
                        Log.d(TAG, "The field '" + key + "' was not added to the bundle");
                    }
                }
            }
            clazz = clazz.getSuperclass();
        }
    }

    /**
     * Load all saved fields that have the {@link SaveInstance} annotation.
     *
     * @param savedInstanceState
     *         The saved-instance {@link Bundle} from an {@link Activity} or {@link Fragment}.
     * @param classInstance
     *         The object to access the fields which have the {@link SaveInstance} annotation.
     * @see #save(Bundle, Object)
     */
    public static void load(Bundle savedInstanceState, Object classInstance) {
        load(savedInstanceState, classInstance, classInstance.getClass());
    }

    /**
     * Load all saved fields that have the {@link SaveInstance} annotation.
     *
     * @param savedInstanceState
     *         The saved-instance {@link Bundle} from an {@link Activity} or {@link Fragment}.
     * @param classInstance
     *         The object to access the fields which have the {@link SaveInstance} annotation.
     * @param baseClass
     *         Base class, used to get all superclasses of the instance.
     * @see #save(Bundle, Object, Class)
     */
    public static void load(Bundle savedInstanceState, Object classInstance, Class<?> baseClass) {
        if (savedInstanceState == null) {
            return;
        }
        Class<?> clazz = classInstance.getClass();
        while (baseClass.isAssignableFrom(clazz)) {
            String className = clazz.getName();
            for (Field field : clazz.getDeclaredFields()) {
                if (field.isAnnotationPresent(SaveInstance.class)) {
                    String key = className + "#" + field.getName();
                    field.setAccessible(true);
                    try {
                        Object fieldVal = savedInstanceState.get(key);
                        if (fieldVal != null) {
                            field.set(classInstance, fieldVal);
                        }
                    } catch (Throwable t) {
                        Log.d(TAG, "The field '" + key + "' was not retrieved from the bundle");
                    }
                }
            }
            clazz = clazz.getSuperclass();
        }
    }

}

Ejemplo de uso:

public class MainActivity extends Activity {

    @SaveInstance
    private String foo;

    @SaveInstance
    private int bar;

    @SaveInstance
    private Intent baz;

    @SaveInstance
    private boolean qux;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Icicle.load(savedInstanceState, this);
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        Icicle.save(outState, this);
    }

}

Nota: Este código fue adaptado de un proyecto de biblioteca llamado AndroidAutowire que es licencia bajo la licencia MIT .

 26
Author: Jared Rummler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-20 02:04:11

Para responder directamente a la pregunta original. savedInstanceState es null porque tu actividad nunca se está recreando.

Su actividad solo se volverá a crear con un paquete de estado cuando:

  • Cambios en la configuración, como cambiar la orientación o el idioma del teléfono, lo que puede requerir la creación de una nueva instancia de actividad.
  • Vuelve a la aplicación desde el fondo después de que el sistema operativo haya destruido la actividad.

Android destruirá el fondo actividades cuando están bajo presión de memoria o después de haber estado en segundo plano durante un período prolongado de tiempo.

Al probar su ejemplo de hello world, hay algunas maneras de salir y volver a la Actividad.

  • Cuando presiona el botón atrás, la Actividad ha terminado. Relanzar la aplicación es una instancia completamente nueva. Usted no está reanudando desde el fondo en absoluto.
  • Cuando presiona el botón de inicio o usa el conmutador de tareas, la Actividad pasará a un segundo plano. Cuando navegar de vuelta a la aplicación onCreate solo se llamará si la Actividad tuvo que ser destruida.

En la mayoría de los casos, si solo presiona inicio y luego vuelve a iniciar la aplicación, no será necesario volver a crear la actividad. Ya existe en la memoria por lo que onCreate () no será llamada.

Hay una opción en Configuración -> Opciones de desarrollador llamada "No mantener actividades". Cuando está habilitado, Android siempre destruirá las actividades y las recreará cuando estén en segundo plano. Esta es una gran opción para dejar habilitado al desarrollar porque simula el peor de los casos. (Un dispositivo de baja memoria que recicla sus actividades todo el tiempo).

Las otras respuestas son valiosas ya que te enseñan las formas correctas de almacenar el estado, pero no sentí que realmente respondieran POR QUÉ tu código no funcionaba de la manera que esperabas.

 24
Author: Jared Kells,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-21 02:19:16

Los métodos onSaveInstanceState(bundle) y onRestoreInstanceState(bundle) son útiles para la persistencia de datos simplemente mientras se gira la pantalla (cambio de orientación).
Ni siquiera son buenos al cambiar entre aplicaciones (ya que el método onSaveInstanceState() se llama pero onCreate(bundle) y onRestoreInstanceState(bundle) no se invoca de nuevo.
Para obtener más persistencia, utilice preferencias compartidas. lea este artículo

 22
Author: Mahorad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-18 04:04:07

Mi problema era que necesitaba persistencia solo durante la vida útil de la aplicación (es decir, una sola ejecución que incluía iniciar otras subactividades dentro de la misma aplicación y rotar el dispositivo, etc.). Probé varias combinaciones de las respuestas anteriores, pero no obtuve lo que quería en todas las situaciones. Al final, lo que funcionó para mí fue obtener una referencia al savedInstanceState durante onCreate:

mySavedInstanceState=savedInstanceState;

Y utilizar que para obtener el contenido de mi variable cuando lo necesitaba, a lo largo de la líneas de:

if (mySavedInstanceState !=null) {
   boolean myVariable = mySavedInstanceState.getBoolean("MyVariable");
}

Utilizo onSaveInstanceState y onRestoreInstanceState como se sugirió anteriormente, pero supongo que también podría usar mi método para guardar la variable cuando cambie (por ejemplo, usando putBoolean)

 14
Author: torwalker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-16 17:11:47

Aunque la respuesta aceptada es correcta, hay un método más rápido y fácil para guardar el estado de la actividad en Android usando una biblioteca llamada Icepick. Icepick es un procesador de anotación que se encarga de todo el código repetitivo utilizado para guardar y restaurar el estado por usted.

Haciendo algo como esto con Icepick:

class MainActivity extends Activity {
  @State String username; // These will be automatically saved and restored
  @State String password;
  @State int age;

  @Override public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Icepick.restoreInstanceState(this, savedInstanceState);
  }

  @Override public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    Icepick.saveInstanceState(this, outState);
  }
}

Es lo mismo que hacer esto:

class MainActivity extends Activity {
  String username;
  String password;
  int age;

  @Override
  public void onSaveInstanceState(Bundle savedInstanceState) {
    super.onSaveInstanceState(savedInstanceState);
    savedInstanceState.putString("MyString", username);
    savedInstanceState.putString("MyPassword", password);
    savedInstanceState.putInt("MyAge", age); 
    /* remember you would need to actually initialize these variables before putting it in the
    Bundle */
  }

  @Override
  public void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    username = savedInstanceState.getString("MyString");
    password = savedInstanceState.getString("MyPassword");
    age = savedInstanceState.getInt("MyAge");
  }
}

Icepick funcionará con cualquier objeto que guarda su estado con un Bundle.

 11
Author: Kevin Cronly,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-26 03:07:39

Básicamente hay dos maneras de implementar este cambio.

  1. usando onSaveInstanceState() y onRestoreInstanceState().
  2. En manifiesto android:configChanges="orientation|screenSize".

Realmente no recomiendo usar el segundo método. Ya que en una de mis experiencias estaba causando la mitad de la pantalla del dispositivo en negro mientras giraba de retrato a paisaje y viceversa.

Usando el primer método mencionado anteriormente , podemos persistir los datos cuando se cambia la orientación o ocurre cualquier cambio de configuración. Sé una manera en la que puedes almacenar cualquier tipo de datos dentro del objeto savedInstance state.

Ejemplo: Considere un caso si desea persistir el objeto Json. cree una clase modelo con getters y setters .

class MyModel extends Serializable{
JSONObject obj;

setJsonObject(JsonObject obj)
{
this.obj=obj;
}

JSONObject getJsonObject()
return this.obj;
} 
}

Ahora en su actividad en el método onCreate y onaveinstancestate haga lo siguiente. Se verá algo como esto:

@override
onCreate(Bundle savedInstaceState){
MyModel data= (MyModel)savedInstaceState.getSerializable("yourkey")
JSONObject obj=data.getJsonObject();
//Here you have retained JSONObject and can use.
}


@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//Obj is some json object 
MyModel dataToSave= new MyModel();
dataToSave.setJsonObject(obj);
oustate.putSerializable("yourkey",dataToSave); 

}
 11
Author: Krishna,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-22 05:48:59

Cuando se crea una actividad se llama al método onCreate ().

   @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

SavedInstanceState es un objeto de la clase Bundle que es null por primera vez, pero contiene valores cuando se vuelve a crear. Para guardar el estado de la actividad tienes que anular onaveinstancestate ().

   @Override
    protected void onSaveInstanceState(Bundle outState) {
      outState.putString("key","Welcome Back")
        super.onSaveInstanceState(outState);       //save state
    }

Ponga sus valores en el objeto de paquete "outState" como outState.putString ("key"," Welcome Back") y save llamando a super. Cuando se destruirá la actividad, su estado se guardará en el objeto Bundle y puede se restaurará después de la recreación en onCreate () o onRestoreInstanceState (). Los paquetes recibidos en onCreate() y onRestoreInstanceState () son los mismos.

   @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

          //restore activity's state
         if(savedInstanceState!=null){
          String reStoredString=savedInstanceState.getString("key");
            }
    }

O

  //restores activity's saved state
 @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
      String restoredMessage=savedInstanceState.getString("key");
    }
 10
Author: Mansuu....,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-23 10:29:47

Aquí hay un comentario de La respuesta de Steve Moseley (por ToolmakerSteve) que pone las cosas en perspectiva (en toda la sagaavaveinstancestate vs onPause, east cost vs west cost)

@VVK - Estoy parcialmente en desacuerdo. Algunas formas de salir de una aplicación no se activan onSaveInstanceState (oSIS). Esto limita la utilidad de las IIS. Su vale la pena apoyar, para los recursos mínimos del sistema operativo, pero si una aplicación quiere devolver al usuario al estado en el que se encontraba, sin importar cómo la aplicación ser al salir, es necesario utilizar un enfoque de almacenamiento persistente en su lugar. Uso onCreate para comprobar si hay paquete, y si falta, entonces compruebe almacenamiento persistente. Esto centraliza la toma de decisiones. Puedo recuperarse de un bloqueo, o salir del botón atrás o salir del elemento de menú personalizado, o volver a la pantalla del usuario estaba en muchos días más tarde. – Fabricante de herramientas 19 '15 a las 10:38

 8
Author: samis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-07 16:02:51

Código Kotlin:

Guardar:

override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState.apply {
        putInt("intKey", 1)
        putString("stringKey", "String Value")
        putParcelable("parcelableKey", parcelableObject)
    })
}

Y luego en onCreate() o onRestoreInstanceState()

    val restoredInt = savedInstanceState?.getInt("intKey") ?: 1 //default int
    val restoredString = savedInstanceState?.getString("stringKey") ?: "default string"
    val restoredParcelable = savedInstanceState?.getParcelable<ParcelableClass>("parcelableKey") ?: ParcelableClass() //default parcelable

Agregue valores predeterminados si no desea tener Opcionales

 7
Author: Rafols,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-12 19:42:32

No estoy seguro de si mi solución está mal vista o no, pero uso un servicio enlazado para persistir en el estado de ViewModel. Si lo almacena en memoria en el servicio o persiste y recupera desde una base de datos SQLLite depende de sus requisitos. Esto es lo que hacen los servicios de cualquier tipo, proporcionan servicios como el mantenimiento del estado de la aplicación y la lógica de negocio común abstracta.

Debido a las limitaciones de memoria y procesamiento inherentes a los dispositivos móviles, trato las vistas de Android de una manera similar a una página web. La página no mantiene el estado, es puramente un componente de capa de presentación cuyo único propósito es presentar el estado de la aplicación y aceptar la entrada del usuario. Las tendencias recientes en la arquitectura de aplicaciones web emplean el uso del patrón antiguo Modelo, Vista, Controlador (MVC), donde la página es la Vista, los datos de dominio son el modelo y el controlador se encuentra detrás de un servicio web. El mismo patrón se puede emplear en Android con la vista bien ... la vista, el modelo son sus datos de dominio y el Controller se implementa como un servicio vinculado a Android. Siempre que desee que una vista interactúe con el controlador, vincule a ella al iniciar/reanudar y desíndela al detener/pausar.

Este enfoque le da la ventaja adicional de hacer cumplir el principio de diseño de Separación de Preocupación en que toda la lógica de negocio de la aplicación se puede mover a su servicio, lo que reduce la lógica duplicada a través de múltiples vistas y permite que la vista haga cumplir otro principio de diseño importante, la Responsabilidad única.

 5
Author: ComeIn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-09 12:57:37

Simple rápido para resolver este problema está utilizando IcePick

Primero, configure la biblioteca en app/build.gradle

repositories {
  maven {url "https://clojars.org/repo/"}
}
dependencies {
  compile 'frankiesardo:icepick:3.2.0'
  provided 'frankiesardo:icepick-processor:3.2.0'
}

Ahora, vamos a comprobar este ejemplo a continuación cómo guardar el estado en la actividad

public class ExampleActivity extends Activity {
  @State String username; // This will be automatically saved and restored

  @Override public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Icepick.restoreInstanceState(this, savedInstanceState);
  }

  @Override public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    Icepick.saveInstanceState(this, outState);
  }
}

Funciona para Actividades, Fragmentos o cualquier objeto que necesite serializar su estado en un Paquete (por ejemplo, ViewPresenters de mortar)

Icepick también puede generar el código de estado de instancia para Vistas personalizadas:

class CustomView extends View {
  @State int selectedPosition; // This will be automatically saved and restored

  @Override public Parcelable onSaveInstanceState() {
    return Icepick.saveInstanceState(this, super.onSaveInstanceState());
  }

  @Override public void onRestoreInstanceState(Parcelable state) {
    super.onRestoreInstanceState(Icepick.restoreInstanceState(this, state));
  }

  // You can put the calls to Icepick into a BaseCustomView and inherit from it
  // All Views extending this CustomView automatically have state saved/restored
}
 5
Author: THANN Phearum,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-14 02:26:57

Para obtener los datos del estado de actividad almacenados en onCreate(), primero debe guardar los datos en savedInstanceState reemplazando el método SaveInstanceState(Bundle savedInstanceState).

Cuando se llama al método activity destroy SaveInstanceState(Bundle savedInstanceState) y allí se guardan los datos que desea guardar. Y obtienes lo mismo en onCreate() cuando se reinicia la actividad.(savedInstanceState no será nulo ya que ha guardado algunos datos en él antes de que la actividad se destruya)

 5
Author: ascii_walker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-03 12:02:09

Ahora Android proporciona ViewModels para guardar el estado, deberías intentar usarlo en lugar de saveInstanceState.

 1
Author: M Abdul Sami,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-27 11:51:27

Agregar LiveData (Componentes de Arquitectura Android) a tu proyecto

Agregue la siguiente dependencia

Implementación "android.arco.ciclo de vida: extensiones: 1.1.0 "

LiveData recibe a un observador y le notifica sobre los cambios de datos solo cuando está en estado INICIADO o REANUDADO. La ventaja con LiveData es que cuando su actividad entra en cualquier estado que no sea INICIADO o REANUDADO no llamará al método onChanged en el observador.

private TextView mTextView;
private MutableLiveData<String> mMutableLiveData;

@Override
protected void onCreate(Bundle savedInstanceState) {
    mTextView = (TextView) findViewById(R.id.textView);
    mMutableLiveData = new MutableLiveData<>();
    mMutableLiveData.observe(this, new Observer<String>() {
        @Override
        public void onChanged(@Nullable String s) {
            mTextView.setText(s);
        }
    });

}
 0
Author: Shomu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-10-11 06:53:04