Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Las actividades son un elemento básico fundamental de las aplicaciones Android y pueden existir en varios estados. El ciclo de vida de la actividad comienza con la instanciación y termina con la destrucción, e incluye muchos estados entre medias. Cuando una actividad cambia de estado, se llama al método de evento de ciclo de vida adecuado, notificando la actividad del cambio de estado inminente y permitiendo que ejecute código para adaptarse a ese cambio. En este artículo se examina el ciclo de vida de las actividades y se explica la responsabilidad que tiene una actividad durante cada uno de estos cambios de estado para formar parte de una aplicación confiable y bien estructurada.
Información general sobre el ciclo de vida de la actividad
Las actividades son un concepto de programación inusual específico de Android. En el desarrollo de aplicaciones tradicional, normalmente hay un método principal estático, que se ejecuta para iniciar la aplicación. Sin embargo, con Android, las cosas son diferentes; Las aplicaciones Android se pueden iniciar a través de cualquier actividad registrada dentro de una aplicación. En la práctica, la mayoría de las aplicaciones solo tendrán una actividad específica que se especifica como punto de entrada de la aplicación. Sin embargo, si una aplicación se bloquea o es finalizada por el sistema operativo, el sistema operativo puede intentar reiniciar la aplicación en la última actividad abierta o en cualquier otro lugar de la pila de actividades anterior. Además, el sistema operativo puede pausar las actividades cuando no están activas y reclamarlas si tiene poca memoria. Debe tenerse en cuenta detenidamente para permitir que la aplicación restaure correctamente su estado en caso de que se reinicie una actividad, especialmente si esa actividad depende de los datos de las actividades anteriores.
El ciclo de vida de la actividad se implementa como una colección de métodos que el sistema operativo llama a lo largo del ciclo de vida de una actividad. Estos métodos permiten a los desarrolladores implementar la funcionalidad necesaria para satisfacer los requisitos de administración de recursos y estado de sus aplicaciones.
Es muy importante que el desarrollador de aplicaciones analice los requisitos de cada actividad para determinar qué métodos expuestos por el ciclo de vida de la actividad deben implementarse. Si no se hace esto, puede dar lugar a la inestabilidad de la aplicación, fallos, sobrecarga de recursos y posiblemente incluso la inestabilidad subyacente del sistema operativo.
En este capítulo se examina detalladamente el ciclo de vida de la actividad, entre los que se incluyen:
- Estados de actividad
- Métodos del ciclo de vida
- Conservar el estado de una aplicación
En esta sección también se incluye un tutorial que proporciona ejemplos prácticos sobre cómo guardar el estado de forma eficaz durante el ciclo de vida de la actividad. Al final de este capítulo, debería comprender el ciclo de vida de la Actividad y cómo admitirlo en una aplicación de Android.
Ciclo de vida de la actividad
El ciclo de vida de la actividad de Android consta de una colección de métodos expuestos dentro de la clase Activity que proporcionan al desarrollador un marco de administración de recursos. Este marco permite a los desarrolladores cumplir los requisitos de administración de estado únicos de cada actividad dentro de una aplicación y controlar correctamente la administración de recursos.
Estados de actividad
El sistema operativo Android arbitra las actividades en función de su estado. Esto ayuda a Android a identificar las actividades que ya no están en uso, lo que permite al sistema operativo reclamar memoria y recursos. En el diagrama siguiente se muestran los estados en los que una actividad puede pasar durante su vigencia:
Estos estados se pueden dividir en 4 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 actividad. Esto se considera la actividad de prioridad más alta en Android y, como tal, el sistema operativo solo eliminará en situaciones extremas, como si la actividad intenta usar más memoria de la que está disponible en el dispositivo, ya que esto podría hacer que la interfaz de usuario deje de responder.
Pausado : cuando el dispositivo entra en suspensión, o una actividad sigue visible pero parcialmente oculta por una actividad nueva, no de tamaño completo o transparente, la actividad se considera pausada. Las actividades en pausa siguen activas, es decir, mantienen toda la información de estado y miembro y permanecen adjuntas al administrador de ventanas. Esto se considera la segunda actividad de prioridad más alta en Android y, como tal, solo la matará el sistema operativo si la eliminación de esta actividad cumplirá los requisitos de recursos necesarios para mantener estable y dinámica la actividad activa/en ejecución.
Detenido/En segundo plano : las actividades que están completamente ocultas por otra actividad se consideran detenidas o en segundo plano. Las actividades detenidas siguen intentando conservar su estado y la información de los miembros durante tanto tiempo como sea posible, pero las actividades detenidas se consideran la prioridad más baja de los tres estados y, como tal, el sistema operativo eliminará las actividades en este estado en primer lugar para satisfacer los requisitos de recursos de las actividades de mayor prioridad.
Reiniciada: es posible que Android quite de la memoria una actividad que esté en cualquier lugar desde una pausa hasta que se detenga en el ciclo de vida. Si el usuario vuelve a la actividad, se debe reiniciar, restaurar a su estado guardado anteriormente y, a continuación, mostrarlo al usuario.
Actividad Re-Creation en respuesta a cambios de configuración
Para complicar aún más las cosas, Android introduce una complicación más en la mezcla, llamada Cambios de configuración. Los cambios de configuración son ciclos rápidos de destrucción o re-creación de actividades que se producen cuando cambia la configuración de una actividad, como cuando se gira el dispositivo (y la actividad necesita volver a compilarse en modo horizontal o vertical), cuando se muestra el teclado (y la actividad se presenta con la oportunidad de cambiar su tamaño), o cuando el dispositivo se coloca en una base, entre otros.
Los cambios de configuración siguen causando los mismos cambios de estado de actividad que se producirían durante la detención y reinicio de una actividad. Sin embargo, para asegurarse de que una aplicación parezca ágil y ofrezca un buen rendimiento durante los cambios de configuración, es importante que se gestionen tan pronto como sea posible. Por este motivo, Android tiene una API específica que se puede usar para conservar el estado durante los cambios de configuración. Trataremos esto más adelante en la sección Administración del estado a lo largo del ciclo de vida .
Métodos de ciclo de vida de actividad
Android SDK y, por extensión, el marco de Xamarin.Android proporciona un modelo eficaz para administrar el estado de las actividades dentro de una aplicación. Cuando cambia el estado de una actividad, el sistema operativo notifica a la actividad, que llama a métodos específicos de esa actividad. En el diagrama siguiente se muestran estos métodos en relación con el ciclo de vida de la actividad:
Como desarrollador, puede controlar los cambios de estado invalidando estos métodos dentro de una actividad. Sin embargo, es importante tener en cuenta que se llama a todos los métodos de ciclo de vida en el subproceso de la interfaz de usuario y impedirá que el sistema operativo realice el siguiente trabajo de la interfaz de usuario, como ocultar la actividad actual, mostrar una nueva actividad, etc. Por lo tanto, el código de estos métodos debe ser lo más breve posible para que una aplicación se sienta bien funcionando. Las tareas de ejecución larga se deben ejecutar en un subproceso en segundo plano.
Vamos a examinar cada uno de estos métodos de ciclo de vida y su uso:
OnCreate
OnCreate es el primer método al que se llamará cuando se crea una actividad.
OnCreate siempre se reemplaza para realizar las inicializaciones de inicio que pueda requerir una Actividad como:
- Creación de vistas
- Inicialización de variables
- Enlazar datos estáticos a listas
OnCreate toma un parámetro Bundle , que es un diccionario para almacenar y pasar información de estado y objetos entre actividades Si la agrupación no es null, esto indica que la actividad se está reiniciando y debe restaurar su estado de la instancia anterior. En el código siguiente se muestra cómo recuperar valores de la agrupación:
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
string intentString;
bool intentBool;
if (bundle != null)
{
intentString = bundle.GetString("myString");
intentBool = bundle.GetBoolean("myBool");
}
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
}
Una vez que OnCreate haya finalizado, Android llamará a OnStart.
OnStart
El sistema siempre llama a OnStart después de que OnCreate haya finalizado. Las actividades pueden invalidar este método si necesitan realizar tareas específicas justo antes de que una actividad se vuelva visible, como actualizar los valores actuales de las vistas dentro de la actividad. Android llamará inmediatamente OnResume después de este método.
OnResume
El sistema llama a OnResume cuando la actividad está lista para empezar a interactuar con el usuario. Las actividades deben invalidar este método para realizar tareas como:
- Aumentar las velocidades de fotogramas (una tarea común en el desarrollo de juegos)
- Inicio de animaciones
- Escucha de actualizaciones de GPS
- Mostrar las alertas o diálogos pertinentes
- Conexión de controladores de eventos externos
Por ejemplo, el siguiente fragmento de código muestra cómo inicializar la cámara:
protected override void OnResume()
{
base.OnResume(); // Always call the superclass first.
if (_camera==null)
{
// Do camera initializations here
}
}
OnResume es importante porque cualquier operación que se realiza en OnPause debe deshacerse en OnResume, ya que es el único método de ciclo de vida que se garantiza que se ejecute después de OnPause al devolver la actividad de vuelta a la vida.
OnPause
Se llama a OnPause cuando el sistema está a punto de colocar la actividad en segundo plano o cuando la actividad se oculta parcialmente. Las actividades deben sobrescribir este método si necesitan:
Confirmar cambios no guardados en datos persistentes
Destruir o limpiar otros objetos que consumen recursos
Aumentar las velocidades de fotogramas y pausar animaciones
Anule el registro de controladores de eventos externos o controladores de notificación (es decir, los que están vinculados a un servicio). Esto debe hacerse para evitar pérdidas de memoria de actividad.
Del mismo modo, si la actividad ha mostrado cuadros de diálogo o alertas, deben limpiarse con el método
.Dismiss().
Por ejemplo, el siguiente fragmento de código liberará la cámara, ya que la actividad no puede usarlo mientras está en pausa:
protected override void OnPause()
{
base.OnPause(); // Always call the superclass first
// Release the camera as other activities might need it
if (_camera != null)
{
_camera.Release();
_camera = null;
}
}
Hay dos métodos de ciclo de vida posibles a los que se llamará después de OnPause:
-
OnResumese llamará si se va a devolver la actividad al primer plano. -
OnStopse llamará si la actividad se coloca en segundo plano.
OnStop
Se llama a OnStop cuando la actividad ya no es visible para el usuario. Esto sucede cuando se produce una de las siguientes acciones:
- Se está iniciando una nueva actividad que cubre esta actividad.
- Se está llevando una actividad existente al primer plano.
- La actividad está siendo destruida.
OnStop es posible que no siempre se invoque en situaciones de memoria baja, como cuando Android carece de recursos y no puede gestionar la actividad en segundo plano correctamente. Por este motivo, es mejor no confiar en que se llame a OnStop al preparar una actividad para la interrupción. Los métodos de ciclo de vida siguientes a los que se puede llamar después de este serán OnDestroy si la actividad va a desaparecer o OnRestart si la actividad vuelve a interactuar con el usuario.
OnDestroy
OnDestroy es el método final al que se llama en una instancia de Activity antes de que se destruya y se quite completamente de la memoria. En situaciones extremas, Android puede eliminar el proceso de aplicación que hospeda la actividad, lo que provocará OnDestroy que no se invoque. La mayoría de las actividades no implementarán este método porque las tareas de limpieza y apagado se han realizado principalmente en los métodos OnPause y OnStop. Normalmente, el método OnDestroy se invalida para limpiar las tareas de larga duración que podrían filtrar recursos. Un ejemplo de esto podría ser subprocesos en segundo plano que se iniciaron en OnCreate.
No se llamará a ningún método de ciclo de vida después de destruir la actividad.
OnRestart
Se invoca a OnRestart después de que tu actividad se haya detenido, y antes de que se inicie de nuevo. Un buen ejemplo de esto sería cuando el usuario presiona el botón inicio mientras está en una actividad de la aplicación. Cuando esto sucede, se llaman los métodos OnPause y OnStop, y la Actividad se mueve a segundo plano, pero no se destruye. Si el usuario fuera a restaurar la aplicación mediante el administrador de tareas o una aplicación similar, Android llamará al OnRestart método de la actividad.
No hay ninguna guía general para qué tipo de lógica se debe implementar en OnRestart. Esto se debe a que OnStart siempre se invoca independientemente de si se crea o se reinicia la actividad, por lo que los recursos necesarios para la actividad se deben inicializar en , en OnStartlugar de OnRestart.
El siguiente método de ciclo de vida llamado después OnRestart será OnStart.
Atrás frente a Página principal
Muchos dispositivos Android tienen dos botones distintos: un botón "Atrás" y un botón "Inicio". Se puede ver un ejemplo de esto en la captura de pantalla siguiente de Android 4.0.3:
Hay una diferencia sutil entre los dos botones, aunque parecen tener el mismo efecto de colocar una aplicación en segundo plano. Cuando un usuario hace clic en el botón Atrás, le indica a Android que ha terminado con la actividad. Android destruirá la actividad. Por el contrario, cuando el usuario hace clic en el botón Inicio, la actividad se coloca simplemente en segundo plano: Android no eliminará la actividad.
Administración del estado a lo largo del ciclo de vida
Cuando se detiene o destruye una actividad, el sistema ofrece la oportunidad de guardar el estado de la actividad para la rehidratación posterior. Este estado guardado se conoce como estado de instancia. Android proporciona tres opciones para almacenar el estado de la instancia durante el ciclo de vida de la actividad:
Almacenar valores primitivos en un
Dictionaryconocido como Bundle que Android utilizará para guardar el estado.Crear una clase personalizada que contenga valores complejos, como mapas de bits. Android usará esta clase personalizada para guardar el estado.
Evitar el ciclo de vida de cambio de configuración y asumir la responsabilidad total de mantener el estado en la actividad.
En esta guía se tratan las dos primeras opciones.
Estado del paquete
La opción principal para guardar el estado de la instancia es usar un diccionario de clave-valor conocido como Bundle.
Recuerde que cuando se crea una actividad que el OnCreate método pasa un lote como parámetro, este lote se puede usar para restaurar el estado de la instancia. No se recomienda usar una agrupación para datos más complejos que no se serializarán rápidamente ni fácilmente en pares clave-valor (como mapas de bits); en su lugar, debe usarse para valores simples como cadenas.
Una actividad proporciona métodos para ayudar a guardar y recuperar el estado de la instancia en el paquete:
OnSaveInstanceState : android invoca esto cuando se destruye la actividad. Las actividades pueden implementar este método si necesitan conservar cualquier elemento de estado de clave-valor.
OnRestoreInstanceState : se llama una vez finalizado el método y proporciona otra oportunidad para que una actividad restaure su estado una vez completada la
OnCreateinicialización.
En el diagrama siguiente se muestra cómo se usan estos métodos:
OnSaveInstanceState
Se llamará a OnSaveInstanceState cuando la actividad esté siendo detenida. Recibirá un parámetro de agrupación en el que la actividad puede almacenar su estado. Cuando un dispositivo experimenta un cambio de configuración, una actividad puede usar el objeto Bundle que se pasa para conservar el estado actividad invalidando OnSaveInstanceState. Por ejemplo, considere el código siguiente:
int c;
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
this.SetContentView (Resource.Layout.SimpleStateView);
var output = this.FindViewById<TextView> (Resource.Id.outputText);
if (bundle != null) {
c = bundle.GetInt ("counter", -1);
} else {
c = -1;
}
output.Text = c.ToString ();
var incrementCounter = this.FindViewById<Button> (Resource.Id.incrementCounter);
incrementCounter.Click += (s,e) => {
output.Text = (++c).ToString();
};
}
El código anterior incrementa un entero denominado c cuando se hace clic en un botón denominado incrementCounter, mostrando el resultado en un TextView denominado output. Cuando se produce un cambio de configuración (por ejemplo, cuando se gira el dispositivo), el código anterior perdería el valor de c porque bundle sería null, como se muestra en la ilustración siguiente:
Para conservar el valor de c en este ejemplo, la actividad puede invalidar OnSaveInstanceStatey guardar el valor en la agrupación, como se muestra a continuación:
protected override void OnSaveInstanceState (Bundle outState)
{
outState.PutInt ("counter", c);
base.OnSaveInstanceState (outState);
}
Ahora, cuando el dispositivo gira a una nueva orientación, el entero se guarda en la agrupación y se recupera con la línea:
c = bundle.GetInt ("counter", -1);
Nota:
Es importante llamar siempre a la implementación base de OnSaveInstanceState para que también se pueda guardar el estado de la jerarquía de vistas.
Ver estado
La invalidación de OnSaveInstanceState es un mecanismo adecuado para guardar datos transitorios en una actividad en los cambios de orientación, como el contador del ejemplo anterior. Sin embargo, la implementación predeterminada de OnSaveInstanceState se encargará de guardar datos transitorios en la interfaz de usuario para cada vista, siempre que cada vista tenga asignado un identificador. Por ejemplo, supongamos que una aplicación tiene un EditText elemento definido en XML de la siguiente manera:
<EditText android:id="@+id/myText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
Puesto que el EditText control tiene id asignado, cuando el usuario escribe algunos datos y gira el dispositivo, los datos se siguen mostrando, como se muestra a continuación:
OnRestoreInstanceState
Se llamará a OnRestoreInstanceState después de OnStart. Proporciona una actividad la oportunidad de restaurar cualquier estado que se guardó anteriormente en un Bundle durante el anterior OnSaveInstanceState. Sin embargo, este es el mismo paquete que se proporciona a OnCreate.
En el código siguiente se muestra cómo se puede restaurar el estado en OnRestoreInstanceState:
protected override void OnRestoreInstanceState(Bundle savedState)
{
base.OnRestoreInstanceState(savedState);
var myString = savedState.GetString("myString");
var myBool = savedState.GetBoolean("myBool");
}
Este método existe para proporcionar cierta flexibilidad en torno a cuándo se debe restaurar el estado. A veces es más adecuado esperar hasta que se realicen todas las inicializaciones antes de restaurar el estado de la instancia. Además, es posible que una subclase de una actividad existente solo quiera restaurar determinados valores a partir del estado de la instancia. En muchos casos, no es necesario invalidar OnRestoreInstanceState, ya que la mayoría de las actividades pueden restaurar el estado mediante la agrupación proporcionada a OnCreate.
Para obtener un ejemplo de cómo guardar el estado mediante Bundle, consulte el Tutorial: guardado del estado de actividad.
Limitaciones de Bundle
Aunque OnSaveInstanceState facilita el guardado de datos transitorios, tiene algunas limitaciones:
No se llama en todos los casos. Por ejemplo, al presionar Inicio o Atrás para salir de una actividad,
OnSaveInstanceStateno se llamará.El paquete pasado a
OnSaveInstanceStateno está diseñado para objetos grandes, como imágenes. En el caso de objetos grandes, es preferible guardar el objeto desde OnRetainNonConfigurationInstance, como se describe a continuación.Los datos guardados mediante el uso de la agrupación se serializan, lo que puede provocar retrasos.
El estado de agrupación es útil para datos simples que no usan mucha memoria, mientras que los datos de instancia que no son de configuración son útiles para datos más complejos o datos que son costosos de recuperar, como desde una llamada de servicio web o una consulta de base de datos complicada. Los datos de instancia que no son de configuración se guardan en un objeto según sea necesario. En la sección siguiente se presenta OnRetainNonConfigurationInstance como una manera de conservar tipos de datos más complejos mediante cambios de configuración.
Conservar datos complejos
Además de conservar los datos de la agrupación, Android también admite guardar datos reemplazando OnRetainNonConfigurationInstance y devolviendo una instancia de Java.Lang.Object que contiene los datos que se van a conservar. Hay dos ventajas principales de usar OnRetainNonConfigurationInstance para guardar el estado:
El objeto devuelto de
OnRetainNonConfigurationInstancefunciona bien con tipos de datos más grandes y complejos porque la memoria conserva este objeto.El método
OnRetainNonConfigurationInstancese llama bajo demanda y solo cuando es necesario. Esto es más económico que usar una caché manual.
El uso OnRetainNonConfigurationInstance es adecuado para escenarios en los que es costoso recuperar los datos varias veces, como en llamadas de servicio web. Por ejemplo, considere el siguiente código que busca en Twitter:
public class NonConfigInstanceActivity : ListActivity
{
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
SearchTwitter ("xamarin");
}
public void SearchTwitter (string text)
{
string searchUrl = String.Format("http://search.twitter.com/search.json?" + "q={0}&rpp=10&include_entities=false&" + "result_type=mixed", text);
var httpReq = (HttpWebRequest)HttpWebRequest.Create (new Uri (searchUrl));
httpReq.BeginGetResponse (new AsyncCallback (ResponseCallback), httpReq);
}
void ResponseCallback (IAsyncResult ar)
{
var httpReq = (HttpWebRequest)ar.AsyncState;
using (var httpRes = (HttpWebResponse)httpReq.EndGetResponse (ar)) {
ParseResults (httpRes);
}
}
void ParseResults (HttpWebResponse httpRes)
{
var s = httpRes.GetResponseStream ();
var j = (JsonObject)JsonObject.Load (s);
var results = (from result in (JsonArray)j ["results"] let jResult = result as JsonObject select jResult ["text"].ToString ()).ToArray ();
RunOnUiThread (() => {
PopulateTweetList (results);
});
}
void PopulateTweetList (string[] results)
{
ListAdapter = new ArrayAdapter<string> (this, Resource.Layout.ItemView, results);
}
}
Este código recupera los resultados de la web con formato JSON, los analiza y, a continuación, presenta los resultados en una lista, como se muestra en la captura de pantalla siguiente:
Cuando se produce un cambio de configuración (por ejemplo, cuando se gira un dispositivo), el código repite el proceso. Para reutilizar los resultados recuperados originalmente y no provocar llamadas de red innecesarias y redundantes, podemos usar OnRetainNonconfigurationInstance para guardar los resultados, como se muestra a continuación:
public class NonConfigInstanceActivity : ListActivity
{
TweetListWrapper _savedInstance;
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
var tweetsWrapper = LastNonConfigurationInstance as TweetListWrapper;
if (tweetsWrapper != null) {
PopulateTweetList (tweetsWrapper.Tweets);
} else {
SearchTwitter ("xamarin");
}
public override Java.Lang.Object OnRetainNonConfigurationInstance ()
{
base.OnRetainNonConfigurationInstance ();
return _savedInstance;
}
...
void PopulateTweetList (string[] results)
{
ListAdapter = new ArrayAdapter<string> (this, Resource.Layout.ItemView, results);
_savedInstance = new TweetListWrapper{Tweets=results};
}
}
Ahora, cuando se gira el dispositivo, los resultados originales se recuperan de la propiedad LastNonConfiguartionInstance. En este ejemplo, los resultados consisten en un string[] que contiene tweets. Puesto que OnRetainNonConfigurationInstance requiere que se devuelva un Java.Lang.Object, se ajusta el string[] en una clase que subclasee Java.Lang.Object, como se muestra a continuación.
class TweetListWrapper : Java.Lang.Object
{
public string[] Tweets { get; set; }
}
Por ejemplo, al intentar usar un TextView como objeto devuelto de OnRetainNonConfigurationInstance, se producirá una fuga de la actividad, como se muestra en el código siguiente.
TextView _textView;
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
var tv = LastNonConfigurationInstance as TextViewWrapper;
if(tv != null) {
_textView = tv;
var parent = _textView.Parent as FrameLayout;
parent.RemoveView(_textView);
} else {
_textView = new TextView (this);
_textView.Text = "This will leak.";
}
SetContentView (_textView);
}
public override Java.Lang.Object OnRetainNonConfigurationInstance ()
{
base.OnRetainNonConfigurationInstance ();
return _textView;
}
En esta sección, hemos aprendido a conservar datos de estado simples con Bundley a conservar tipos de datos más complejos con OnRetainNonConfigurationInstance.
Resumen
El ciclo de vida de la actividad de Android proporciona un marco eficaz para la administración de estado de las actividades dentro de una aplicación, pero puede resultar complicado comprender e implementar. En este capítulo se introdujeron los distintos estados en los que una actividad puede pasar durante su vigencia, así como los métodos de ciclo de vida asociados a esos estados. A continuación, se proporcionan instrucciones sobre qué tipo de lógica se debe realizar en cada uno de estos métodos.






