Ciclo de vida de la actividad de Android: ¿para qué sirven todos estos métodos?


420

¿Cuál es el ciclo de vida de una actividad de Android? ¿Por qué son tantos métodos que suenan similares ( onCreate(), onStart(), onResume()) llamaron durante la inicialización, y tantos otros ( onPause(), onStop(), onDestroy()) llamaron al final?

¿Cuándo se llaman estos métodos y cómo se deben usar correctamente?


17
¿Por qué esta pregunta ha sido votada tantas veces? ¿Por qué no se ha cerrado?
Alexander Kulyakhtin

54
¿Por qué cerrar una pregunta con muchos votos a favor? Stackoverflow tiene la mala costumbre de eso.
Dick Lucas

12
Esta es una pregunta de estilo wiki y creo que debería permitirse en el sitio.
Mateen Ulhaq

2
@Alexander Kulyakhtin - ¿Por qué cerrar esta pregunta? En su lugar, debe cerrar su cuenta si no puede digerir la información que se proporciona en las respuestas para los nuevos usuarios de Android. Esta pregunta está llena de conocimiento y voy a votar esta pregunta.
Desbordamiento de pila

¿Para cuándo se llaman estos métodos pregunta, qué has intentado?
Sreekanth Karumanaghat

Respuestas:


748

Véalo en Activity Lifecycle (en Desarrolladores de Android).

Ingrese la descripción de la imagen aquí

onCreate () :

Se llama cuando se crea por primera vez la actividad. Aquí es donde debe hacer toda su configuración estática normal: crear vistas, vincular datos a listas, etc. Este método también le proporciona un paquete que contiene el estado previamente congelado de la actividad, si existiera. Siempre seguido de onStart ().

onRestart () :

Llamado después de que su actividad se haya detenido, antes de que se inicie nuevamente. Siempre seguido de onStart ()

onStart () :

Se llama cuando la actividad se vuelve visible para el usuario. Seguido por onResume () si la actividad llega a primer plano.

onResume () :

Llamado cuando la actividad comenzará a interactuar con el usuario. En este punto, su actividad está en la parte superior de la pila de actividades, con la entrada del usuario. Siempre seguido de onPause ().

onPause () :

Se llama como parte del ciclo de vida de la actividad cuando una actividad pasa a un segundo plano, pero (todavía) no se ha eliminado. La contraparte de onResume (). Cuando se inicia la actividad B frente a la actividad A, esta devolución de llamada se invocará en A. B no se creará hasta que regrese onPause () de A, así que asegúrese de no hacer nada largo aquí.

onStop () :

Llamado cuando ya no eres visible para el usuario. Luego recibirá onRestart (), onDestroy () o nada, dependiendo de la actividad posterior del usuario. Tenga en cuenta que este método nunca se puede llamar, en situaciones de poca memoria donde el sistema no tiene suficiente memoria para mantener el proceso de su actividad ejecutándose después de que se llama a su método onPause ().

onDestroy () :

La última llamada que recibe antes de que su actividad sea destruida. Esto puede suceder ya sea porque la actividad está terminando (alguien lo llamó terminar () o porque el sistema está destruyendo temporalmente esta instancia de la actividad para ahorrar espacio. Puede distinguir entre estos dos escenarios con el método isFinishing ().

Cuando la actividad se carga por primera vez, los eventos se llaman de la siguiente manera:

onCreate()
onStart()
onResume()

Cuando hace clic en el botón Teléfono, la Actividad pasa al fondo y se llaman los siguientes eventos:

onPause()
onStop()

Salga del marcador del teléfono y se llamarán los siguientes eventos:

onRestart()
onStart()
onResume()

Cuando hace clic en el botón Atrás O intenta finalizar () la actividad, los eventos se llaman de la siguiente manera:

onPause()
onStop()
onDestroy()

Estados de actividad

El sistema operativo Android utiliza una cola prioritaria para ayudar a administrar las actividades que se ejecutan en el dispositivo. Según el estado en que se encuentre una actividad particular de Android, se le asignará una cierta prioridad dentro del sistema operativo. Este sistema prioritario ayuda a Android a identificar actividades que ya no están en uso, lo que permite que el sistema operativo recupere memoria y recursos. El siguiente diagrama ilustra los estados por los que puede pasar una actividad durante su vida útil:

Estos estados se pueden dividir en tres grupos principales de la siguiente manera:

Activo o en ejecución : las actividades se consideran activas o en ejecución si están en primer plano, también conocidas como la parte superior de la pila de actividades. Esta se considera la actividad de mayor prioridad en la pila de actividades de Android y, como tal, solo será eliminada por el sistema operativo en situaciones extremas, como si la actividad intenta usar más memoria de la disponible en el dispositivo, ya que esto podría causar que la interfaz de usuario dejar de responder

En pausa : cuando el dispositivo se va a dormir, o una actividad aún está visible pero parcialmente oculta por una actividad nueva, no de tamaño completo o transparente, la actividad se considera en pausa. Las actividades pausadas aún están activas, es decir, mantienen toda la información del estado y de los miembros y permanecen adjuntas al administrador de ventanas. Esta se considera la segunda actividad de mayor prioridad en la pila de actividades de Android y, como tal, solo será eliminada por el sistema operativo si la eliminación de esta actividad satisfará los requisitos de recursos necesarios para mantener la actividad activa / en ejecución estable y receptiva.

Detenido : las actividades que están completamente oscurecidas por otra actividad se consideran detenidas o en segundo plano. Las actividades detenidas aún tratan de retener su información de estado y miembro durante el mayor tiempo posible, pero las actividades detenidas se consideran la prioridad más baja de los tres estados y, como tal, el sistema operativo matará las actividades en este estado primero para satisfacer los requisitos de recursos de actividades de mayor prioridad.

* Actividad de muestra para comprender el ciclo de vida **

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends Activity {
    String tag = "LifeCycleEvents";
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.main);
       Log.d(tag, "In the onCreate() event");
    }
    public void onStart()
    {
       super.onStart();
       Log.d(tag, "In the onStart() event");
    }
    public void onRestart()
    {
       super.onRestart();
       Log.d(tag, "In the onRestart() event");
    }
    public void onResume()
    {
       super.onResume();
       Log.d(tag, "In the onResume() event");
    }
    public void onPause()
    {
       super.onPause();
       Log.d(tag, "In the onPause() event");
    }
    public void onStop()
    {
       super.onStop();
       Log.d(tag, "In the onStop() event");
    }
    public void onDestroy()
    {
       super.onDestroy();
       Log.d(tag, "In the onDestroy() event");
    }
}

1
Entonces, si lo entendí correctamente, onStop () siempre se llama después de onPause ()?
Titouan de Bailleul

44
NO siempre, "onStop (): llamado cuando ya no eres visible para el usuario"
Yaqub Ahmad

2
¿Hay algo por casualidad que se llame antes de onCreate?
NodeDad

66
Sí, el constructor predeterminado (ese es el que no tiene parámetros). Pero solo tiene un uso muy limitado para fines de inicialización muy básicos. Por lo general, usted debe no usarlo a menos que realmente sepa lo que está haciendo. E incluso entonces deberías pensarlo dos veces si hay una mejor manera de hacer las cosas.
Mjoellnir

1
Creo que este enlace puede ayudarlo a comprender mejor el ciclo de vida de la actividad. iphtechnologies.com/understanding-lifecycle-in-android-activity
Ashish Kumar Mishra

162

La actividad tiene seis estados.

  • Creado
  • Empezado
  • Reanudado
  • Pausado
  • Detenido
  • Destruido

El ciclo de vida de la actividad tiene siete métodos.

  • onCreate()
  • onStart()
  • onResume()
  • onPause()
  • onStop()
  • onRestart()
  • onDestroy()

ciclo de vida de la actividad

Situaciones

  • Cuando abra la aplicación

    onCreate() --> onStart() -->  onResume()
  • Cuando se presiona el botón Atrás y sale de la aplicación

    onPaused() -- > onStop() --> onDestory()
  • Cuando se presiona el botón de inicio

    onPaused() --> onStop()
  • Después de presionar el botón de inicio cuando vuelve a abrir la aplicación de la lista de tareas recientes o hacer clic en el icono

    onRestart() --> onStart() --> onResume()
  • Al abrir la aplicación, otra aplicación desde la barra de notificaciones o la configuración abierta

    onPaused() --> onStop()
  • El botón Atrás presionado desde otra aplicación o configuración y luego utilizado puede ver nuestra aplicación

    onRestart() --> onStart() --> onResume()
  • Cuando cualquier diálogo se abre en la pantalla

    onPause()
  • Después de cerrar el cuadro de diálogo o el botón Atrás del cuadro de diálogo

    onResume()
  • Cualquier teléfono está sonando y el usuario está en la aplicación

    onPause() --> onResume() 
  • Cuando el usuario presionó el botón de respuesta del teléfono

    onPause()
  • Después de finalizar la llamada

    onResume()
  • Cuando la pantalla del teléfono está apagada

    onPaused() --> onStop()
  • Cuando la pantalla se vuelve a encender

    onRestart() --> onStart() --> onResume()

66
'Cuando se abre un cuadro de diálogo en la pantalla, se llama a onPause ()', no es cierto para un cuadro de diálogo de alerta. Se llama solo cuando el diálogo es en sí mismo una actividad de diálogo (tiene el tema establecido en @android: style / Theme.Dialog).
gaurav jain

2
Valiosa respuesta. Envíe esto a google para agregar a su documentación. ¡Estoy guardando su respuesta a un documento de Word para guardar!
likejudo

No entiendo el mensaje "Cualquier teléfono está sonando y el usuario está en la aplicación". ¿Cuál es el escenario exactamente? La primera fue que si el usuario está en la aplicación y el teléfono comienza a sonar, sería onPause () -> onStop () en caso de que la pantalla completa se convirtiera en la llamada. Para el mensaje de llamada entrante heads-up podría ser solo OnResume -> onPause () pero no estoy seguro de esto. ¿Cuál es la situación en una llamada para onPause -> onResume? ¿Está al final de la llamada?
Sotti

Esto es lo que estaba buscando. Solo quería saber dónde debería poner mi llamada de API.
Heisenberg

Me gustó tu respuesta basada en escenarios .
kokabi

155

Toda la confusión se debe a que Google eligió nombres no intuitivos en lugar de algo de la siguiente manera:

onCreateAndPrepareToDisplay()   [instead of onCreate() ]
onPrepareToDisplay()            [instead of onRestart() ]
onVisible()                     [instead of onStart() ]
onBeginInteraction()            [instead of onResume() ]
onPauseInteraction()            [instead of onPause() ]
onInvisible()                   [instead of onStop]
onDestroy()                     [no change] 

El Diagrama de actividad se puede interpretar como:

ingrese la descripción de la imagen aquí


1
Depende A menos que resuelva la confusión, un nombre largo no está mal. Por ejemplo: onRoutePresentationDisplayChanged () es en gran medida una función desde el SDK de Android
Nilesh Pawar

12
Personalmente, no encuentro sus nombres extremadamente más intuitivos, además de Fragmentos, realmente no se correlaciona.
Martin Marconcini

99
Votado Más útil que la documentación oficial
bad_keypoints

3
Es una gran publicación. Un problema. Cuando escribe los métodos del ciclo de vida de Andoid en Google, esta imagen aparece sobre la opción de búsqueda (ni siquiera en el modo de búsqueda de imágenes) como la respuesta a los métodos del ciclo de vida de Android. Lo inconsciente (o perezoso dependiendo de cómo lo mire) podría confundirse fácilmente a menos que sigan el enlace StackOverflow en lugar de hacer clic en la imagen del diagrama de flujo (su imagen).
Andrew S

1
Si. Esto es lo que he estado buscando. Alguien debería escribir un libro (¿o un documento?) Con cosas como esta. onResume etc. no tiene sentido.
Harsha_K

22

CICLO DE VIDA DE ANDROID

Existen siete métodos que administran el ciclo de vida de una aplicación de Android:


Responda para cuáles son todos estos métodos para:

Tomemos un escenario simple donde saber en qué orden se llaman estos métodos nos ayudará a dar una idea clara de por qué se usan.

  • Supongamos que está utilizando una aplicación de calculadora. Se llaman tres métodos seguidos para iniciar la aplicación.

onCreate() - - -> - - ->onStart() onResume()

  • Cuando estoy usando la aplicación de la calculadora, de repente aparece una llamada. La actividad de la calculadora pasa a un segundo plano y otra actividad dice. Tratar con la llamada pasa a primer plano, y ahora se llaman dos métodos en sucesión.

onPause() - - -> onStop()

  • Ahora digamos que termino la conversación por teléfono, la actividad de la calculadora pasa a primer plano desde el fondo, por lo que se llaman tres métodos sucesivamente.

onRestart() - - -> - - ->onStart() onResume()

  • Finalmente, digamos que he terminado todas las tareas en la aplicación de calculadora y quiero salir de la aplicación. Otros dos métodos se llaman en sucesión.

onStop() - - -> onDestroy()


Hay cuatro estados en los que puede existir una actividad:

  • Estado inicial
  • Estado de ejecución
  • Estado en pausa
  • Estado detenido

El estado inicial implica:

Crear un nuevo proceso de Linux, asignar nueva memoria para los nuevos objetos de IU y configurar toda la pantalla. Entonces, la mayor parte del trabajo está involucrado aquí.

El estado de ejecución implica:

Es la actividad (estado) que está actualmente en la pantalla. Este estado solo maneja cosas como escribir en la pantalla y tocar y hacer clic en los botones.

El estado de pausa implica:

Cuando una actividad no está en primer plano y, en cambio, está en segundo plano, se dice que la actividad está en estado de pausa.

El estado detenido implica:

Una actividad detenida solo se puede comprar en primer plano al reiniciarla y también se puede destruir en cualquier momento.

El administrador de actividades maneja todos estos estados de tal manera que la experiencia y el rendimiento del usuario siempre están en su mejor momento, incluso en escenarios donde la nueva actividad se agrega a las actividades existentes.


¿ Algún ejemplo para onPause to onResume ?
zeeali

14

Me gusta esta pregunta y las respuestas, pero hasta ahora no hay cobertura de devoluciones de llamada de uso menos frecuente como onPostCreate () o onPostResume () . Steve Pomeroy ha intentado un diagrama que incluye estos y cómo se relacionan con elciclo de vida Fragment de Android, en https://github.com/xxv/android-lifecycle . Revisé el gran diagrama de Steve para incluir solo laparte de Actividad y lo formateé para imprimir en letra de una página. Lo publiqué como un PDF de texto en https://github.com/code-read/android-lifecycle/blob/master/AndroidActivityLifecycle1.pdf y debajo está su imagen:

Ciclo de vida de la actividad de Android


8

Desde la página de Desarrolladores de Android,

onPause ():

Se llama cuando el sistema está a punto de comenzar a reanudar una actividad anterior. Esto se usa generalmente para confirmar cambios no guardados en datos persistentes, detener animaciones y otras cosas que pueden estar consumiendo CPU, etc. Las implementaciones de este método deben ser muy rápidas porque la siguiente actividad no se reanudará hasta que este método regrese. Seguido por onResume () si la actividad regresa al frente o onStop () si se vuelve invisible para el usuario.

onStop ():

Se llama cuando la actividad ya no es visible para el usuario, porque otra actividad se ha reanudado y está cubriendo esta. Esto puede suceder porque se está iniciando una nueva actividad, se está trayendo una existente frente a esta o se está destruyendo esta. Seguido por onRestart () si esta actividad vuelve a interactuar con el usuario, o onDestroy () si esta actividad desaparece.

Ahora suponga que hay tres Actividades y usted va de A a B, luego onPause de A será llamado ahora de B a C, luego onPause of B y onStop of A serán llamadas.

La actividad en pausa obtiene un currículum y se detiene reiniciado.

Cuando usted llama this.finish() , onPause-onStop-onDestroy. Lo principal para recordar es: las actividades pausadas se detienen y una actividad detenida se destruye cada vez que Android requiere memoria para otras operaciones.

Espero que sea lo suficientemente claro.


podemos método onPause plazo como una etapa intermedia entre la actividad de comenzar a foco suelta y finalmente convertirse invisble para el usuario y el método OnStop como cuando la actividad se ha convertido completamente invisble para el usuario
Nav

Creo que debería ser así.
Masiar

3
@Nav Suponga que hay 3 actividades y usted va de A a B, entonces onPause de A se llamará ahora de B a C, luego onPause of B y onStop of A se llamarán.
MKJParekh

3

Agregar más información sobre la respuesta altamente calificada (Se agregó una sección adicional de KILLABLE y el siguiente conjunto de métodos, que se llamarán en el ciclo de vida):

Fuente: developer.android.com

ingrese la descripción de la imagen aquí

Tenga en cuenta el " Killable columna " en la tabla anterior: para aquellos métodos que están marcados como eliminables, después de que ese método devuelve, el sistema puede el proceso que aloja la actividad en cualquier momento sin que se ejecute otra línea de su código.

Debido a esto, debe usar el onPause()método para escribir cualquier dato persistente (como las ediciones del usuario) en el almacenamiento. Además, onSaveInstanceState(Bundle)se llama al método antes de colocar la actividad en dicho estado de fondo, lo que le permite guardar cualquier estado de instancia dinámica en su actividad en el dado Bundle, para luego ser recibido onCreate(Bundle)si la actividad necesita ser recreada.

Tenga en cuenta que es importante guardar datos persistentes en onPause()lugar de onSaveInstanceState(Bundle)porque este último no es parte de las devoluciones de llamada del ciclo de vida, por lo que no se llamará en todas las situaciones como se describe en su documentación.

Me gustaría agregar algunos métodos más. Estos no se enumeran como métodos de ciclo de vida, pero se llamarán durante el ciclo de vida dependiendo de algunas condiciones. Dependiendo de sus requisitos, es posible que deba implementar estos métodos en su aplicación para un manejo adecuado del estado.

onPostCreate(Bundle savedInstanceState)

Se llama cuando se completa el inicio de la actividad (después onStart()y onRestoreInstanceState(Bundle)se ha llamado).

onPostResume()

Se llama cuando se completa la reanudación de la actividad (después de que onResume()se ha llamado).

onSaveInstanceState(Bundle outState)

Llamado para recuperar el estado por instancia de una actividad antes de ser eliminado para que el estado pueda restaurarse en onCreate(Bundle)o onRestoreInstanceState(Bundle)(el paquete poblado por este método se pasará a ambos).

onRestoreInstanceState(Bundle savedInstanceState)

Este método se llama después onStart()cuando la actividad se reinicia desde un estado previamente guardado, dado aquí en savedInstanceState.

Mi código de aplicación usando todos estos métodos:

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private EditText txtUserName;
    private EditText txtPassword;
    Button  loginButton;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.d("Ravi","Main OnCreate");
        txtUserName=(EditText) findViewById(R.id.username);
        txtPassword=(EditText) findViewById(R.id.password);
        loginButton =  (Button)  findViewById(R.id.login);
        loginButton.setOnClickListener(this);

    }

    @Override
    public void onClick(View view) {
        Log.d("Ravi", "Login processing initiated");
        Intent intent = new Intent(this,LoginActivity.class);
        Bundle bundle = new Bundle();
        bundle.putString("userName",txtUserName.getText().toString());
        bundle.putString("password",txtPassword.getText().toString());
        intent.putExtras(bundle);
        startActivityForResult(intent,1);
       // IntentFilter
    }
    public void onActivityResult(int requestCode, int resultCode, Intent resIntent){
        Log.d("Ravi back result:", "start");
        String result = resIntent.getStringExtra("result");
        Log.d("Ravi back result:", result);
        TextView txtView = (TextView)findViewById(R.id.txtView);
        txtView.setText(result);

        Intent sendIntent = new Intent();
        //sendIntent.setPackage("com.whatsapp");
        sendIntent.setAction(Intent.ACTION_SEND);
        sendIntent.putExtra(Intent.EXTRA_TEXT, "Message...");
        sendIntent.setType("text/plain");
        startActivity(sendIntent);
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.d("Ravi","Main Start");
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Log.d("Ravi","Main ReStart");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d("Ravi","Main Pause");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d("Ravi","Main Resume");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d("Ravi","Main Stop");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d("Ravi","Main OnDestroy");
    }

    @Override
    public void onPostCreate(Bundle savedInstanceState, PersistableBundle persistentState) {
        super.onPostCreate(savedInstanceState, persistentState);
        Log.d("Ravi","Main onPostCreate");
    }

    @Override
    protected void onPostResume() {
        super.onPostResume();
        Log.d("Ravi","Main PostResume");
    }

    @Override
    public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
        super.onSaveInstanceState(outState, outPersistentState);
    }

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

Actividad de inicio de sesión:

public class LoginActivity extends AppCompatActivity {

    private TextView txtView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        txtView = (TextView) findViewById(R.id.Result);
        Log.d("Ravi","Login OnCreate");
        Bundle bundle = getIntent().getExtras();
        txtView.setText(bundle.getString("userName")+":"+bundle.getString("password"));
        //Intent  intent = new Intent(this,MainActivity.class);
        Intent  intent = new Intent();
        intent.putExtra("result","Success");
        setResult(1,intent);
       // finish();
    }
}

salida: (antes de la pausa)

D/Ravi: Main OnCreate
D/Ravi: Main Start
D/Ravi: Main Resume
D/Ravi: Main PostResume

salida: (después de reanudar desde pausa)

D/Ravi: Main ReStart
D/Ravi: Main Start
D/Ravi: Main Resume
D/Ravi: Main PostResume

Tenga en cuenta que onPostResume()se invoca aunque no se cita como método del ciclo de vida.


0

Ejecuto algunos registros según las respuestas anteriores y aquí está la salida:

Iniciando actividad

On Activity Load (First Time)
————————————————————————————————————————————————
D/IndividualChatActivity: onCreate: 
D/IndividualChatActivity: onStart: 
D/IndividualChatActivity: onResume: 
D/IndividualChatActivity: onPostResume: 

Reload After BackPressed
————————————————————————————————————————————————
D/IndividualChatActivity: onCreate: 
D/IndividualChatActivity: onStart: 
D/IndividualChatActivity: onResume: 
D/IndividualChatActivity: onPostResume: 

OnMaximize(Circle Button)
————————————————————————————————————————————————
D/IndividualChatActivity: onRestart: 
D/IndividualChatActivity: onStart: 
D/IndividualChatActivity: onResume: 
D/IndividualChatActivity: onPostResume: 

OnMaximize(Square Button)
————————————————————————————————————————————————
D/IndividualChatActivity: onRestart: 
D/IndividualChatActivity: onStart: 
D/IndividualChatActivity: onResume: 
D/IndividualChatActivity: onPostResume: 

Deteniendo la actividad

On BackPressed
————————————————————————————————————————————————
D/IndividualChatActivity: onPause:
D/IndividualChatActivity: onStop: 
D/IndividualChatActivity: onDestroy: 

OnMinimize (Circle Button)
————————————————————————————————————————————————
D/IndividualChatActivity: onPause: 
D/IndividualChatActivity: onStop: 

OnMinimize (Square Button)
————————————————————————————————————————————————
D/IndividualChatActivity: onPause: 
D/IndividualChatActivity: onStop: 

Going To Another Activity
————————————————————————————————————————————————
D/IndividualChatActivity: onPause:
D/IndividualChatActivity: onStop: 

Close The App
————————————————————————————————————————————————
D/IndividualChatActivity: onDestroy: 

En mi opinión personal, solo se requieren dos onStart y onStop.

onResume parece estar en cada instancia de regreso, y onPause en cada instancia de partida (excepto para cerrar la aplicación).

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.