lunes, 8 de septiembre de 2014

Actividades

Una actividad es un componente de aplicación que proporciona una pantalla con la que el usuario puede interactuar con el fin de realizar alguna operación, como por ejemplo: hacer una llamada telefónica, hacer una fotografía, enviar un correo electrónico, o ver un mapa. Cada actividad está delimitada por su ventana en la que se muestra la interfaz de usuario. La ventana generalmente ocupa toda la pantalla, pero puede ser más pequeña y flotar sobre otras ventanas.

Una aplicación generalmente está formada por un conjunto de actividades relacionadas entre sí. Una, y solo una, de esas actividades la declararemos como la actividad principal de nuestra aplicación y eso hará que se inicie por defecto cuando el usuario ejecute la aplicación por primera vez.

Una actividad también puede ser iniciada a través de otra actividad con el fin de realizar diferentes acciones. Cuando iniciamos una actividad, ésta se añade a la pila de retroceso (back stack) y pasa a un primer plano, disponible para la interacción con el usuario. Cuando el usuario pulsa el botón de retroceso, la actividad actual se saca del tope de la pila y se destruye, reanudándose la actividad previa. Al sistema de funcionamiento de la pila de retroceso se le conoce por las siglas LIFO (Last In First Out - Último Entra, Primero Sale).

Los cambios de estado que sufre una actividad son comunicados por el sistema mediante la invocación de métodos retrollamada (callbacks) asociados a la propia actividad. Hay varios métodos retrollamada que una actividad puede recibir cuando ésta cambia de estado: cuando el sistema la crea, la detiene, la reanuda, o la destruye. Para cada uno de estos eventos, podremos realizar las operaciones que consideremos necesarias implementando su método correspondiente. Por ejemplo, cuando la actividad es detenida, deberíamos implementar lo necesario para liberar la memoria de objetos pesados, tales como conexiones de red o conexiones a bases de datos. Cuando la actividad se reanuda, recuperaremos los recursos necesarios y continuamos por donde lo habíamos dejado.

Creando nuestra actividad.

Para crear una actividad, extenderemos la clase Activity, (o alguna de sus clases descendientes) e implementaremos los métodos retrollamada necesarios  que el sistema irá invocando a medida que se vayan produciendo cambios de estado. Los dos métodos retrollamada más importantes son:
onCreate()
El sistema llama a este método durante el proceso de creación de la actividad. Dentro de este método, deberíamos crear e inicializar los componentes básicos. Uno de estos componentes es la plantilla donde se encuentra definida la interfaz del usuario. Para asociarle una plantilla a nuestra actividad, utilizaremos el método setContentView() .
 onPause()
Cuando el sistema llama a este método es porque el usuario empieza a abandonar la actividad (esto no significa que la actividad vaya a ser destruida). Este es el punto en que deberíamos guardar cambios persistentes porque puede que el usuario no vuelva reanudar la actividad. 

Implementando la interfaz de usuario.

La interfaz de usuario está formada por un conjunto de vistas relacionadas jerárquicamente y que extienden la clase View. Cada vista controla un espacio rectangular determinado de la ventana de la actividad y puede responder a ciertas acciones del usuario. Por ejemplo, una vista puede ser un botón que hace algo cuando el usuario lo pulsa.

Android nos proporciona un conjunto de vistas predefinidas que podremos usar en el diseño de nuestras plantillas. Los controles (widgets) son vistas que muestran algún elemento con el que se puede interactuar en pantalla, como puede ser un botón, un campo de texto, una casilla de verificación, o una imagen. Los esquemas (layouts) son vistas especiales que contienen otras vistas. Existen varios tipos de esquemas: esquema lineal, esquema cuadrículado, esquema relativo, etc. La diferencia entre un esquema y otro, es la manera en la que muestran las vistas contenidas.

Puedes extender tanto la clase View como la clase ViewGroup para crear tus propios controles y esquemas y utilizarlos en las plantillas de tus actividades.

A la hora de crear la plantilla de una actividad, utilizaremos un archivo XML. Con ello, conseguiremos separar la interfaz del usuario (vista) de la lógica de la actividad. Podremos asociar la plantilla a la actividad a través del método setContentView(), especificando como argumento del método el identificador de la misma. Aunque esta es la manera más habitual de crear una plantilla, también podríamos haberlo hecho de manera dinámica, desde el código y en tiempo de ejecución.

Declarando la actividad en el archivo manifest.

Para que el sistema sea consciente de la existencia de nuestras actividades, tendremos que declararlas en el archivo AndroidManifest.xml (manifest a partir de ahora). Para declarar una actividad, edita este archivo y añade un nuevo elemento <activity> dentro del elemento <application>:
<manifest ... >
  <application ... >
      <activity android:name=".ExampleActivity" />
      ...
  </application ... >
  ...
</manifest >

Nota. Si utilizamos las plantillas predefinidas que Android Studio proporciona para la creación de actividades, será el propio Android Studio el que añada la actividad al archivo manifest por nosotros.

Existen varios atributos asociados al elemento <activity> que nos permitirán especificar entre otros: una etiqueta, un icono, o el tema con el que mostrar la actividad. El único atributo obligatorio es el nombre android:name. En éste, se especifica el nombre de la clase de la actividad. Observa que el nombre se ha prefijado con un punto (.). El punto en este contexto, representa el nombre del paquete de nuestra aplicación (com.mydomain.myapplication, por ejemplo).

Si por alguna razón necesitaras cambiar el nombre de la clase asociada a una actividad, ten en cuenta que dicho nombre también lo encontraremos en el archivo manifest. Utilizando las herramientas que Android Studio proporciona para la refactorización del código, este cambio lo podremos realizar de manera sencilla.

Usando filtros de intenciones.

Dentro de un elemento <activity> puedes definir uno o varios elementos <intent-filter> con el fin de permitir que los componentes de otras aplicaciones puedan iniciar nuestra actividad para realizar una tarea determinada.

Cuando creamos una aplicación utilizando las herramientas del SDK, estaremos además creando una actividad por defecto. Esta actividad es la actividad principal de la aplicación y será la que se inicie cuando el usuario ejecute la aplicación por primera vez. Par conseguir este funcionamiento, la actividad principal tiene definido el siguiente filtro:
<activity android:name=".ExampleActivity" android:icon="@drawable/app_icon">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
Observa que el elemento <action> declara la actividad como la entrada principal a nuestra aplicación (android.intent.action.MAIN). El elemento <category> hace que la actividad aparezca disponible para el usuario desde el lanzador de aplicaciones (android.intent.category.LAUNCHER). Solo una actividad de nuestra aplicación puede tener definido este filtro.

No necesitarás definir filtros adicionales salvo que quieras ofrecer alguna funcionalidad a otras actividades.

Iniciando nuestra actividad.

Podremos iniciar otra actividad llamando al método startActivity(), pasándole como parámetro una intención (Intent) en la que especificaremos la actividad o el tipo de actividad que queremos iniciar. La intención puede hacer referencia a la actividad de manera explícita o de manera implícita (un tipo de actividad). Será el sistema el encargado de encontrar la actividad más adecuada en función los datos contenidos en la intención.

Cuando trabajamos con actividades de nuestra aplicación que son bien conocidas, las intenciones usarán referencias explícitas a dichas actividades. Por ejemplo, si necesitamos iniciar una actividad cuyo nombre de clase es SignInActivity:
Intent intent = new Intent(this, SignInActivity.class);
startActivity(intent);
Nota. Observa que el segundo argumento del constructor de la intención es el objeto de tipo Class para la clase SignInActivity. Esta clase se usa en Java para lo que se denomina reflection (reflexión).

Por otro lado, si queremos reutilizar alguna funcionalidad ya implementada por un tercero, como puede ser el enviar un correo electrónico, o mostrar una imagen, o compartir un recurso, tendremos que hacerlo utilizando una intención implícita. Es decir, tendremos que usar una intención en la que especificaremos el tipo de operación/acción que deseamos realizar:
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_EMAIL, recipientArray);
startActivity(intent);
EXTRA_EMAIL es un valor extra asociado a los datos de la intención, y que en este caso utilizamos para especificar los destinatarios del correo (un array de cadenas de texto conteniendo direcciones de correo electrónico). Cuando una aplicación de correo electrónico responde a esta intención, utilizará este array para rellenar el campo "destinatarios" del mensaje. Una vez el usuario termina el envío, volveremos a la actividad que originó la petición.

Si el sistema encuentra varias actividades que cumplen con los requisitos de la petición, se mostrará un cuadro de diálogo al usuario desde el que podrá seleccionar su aplicación preferida.

Iniciando nuestra actividad y esperando un resultado.

A veces, iniciar una actividad lleva implícito la generación de un resultado que a posteriori utilizaremos en nuestra aplicación. En estos casos, iniciaremos la actividad con el método startActivityForResult(). El resultado de la operación nos vendrá dado en una intención a través del método retrollamada onActivityResult().

Por ejemplo, supongamos que queremos acceder a la agenda de contactos del teléfono, que el usuario seleccione uno y que el valor seleccionado sea devuelto a nuestra actividad:
private void pickContact() {
    // Creamos la intención para seleccionar el contacto.
    // También especificamos información más específica a través del URI.
    Intent intent = new Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI);
    startActivityForResult(intent, PICK_CONTACT_REQUEST);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // Si todo fue bien, procesamos nuestra petición PICK_CONTACT_REQUEST
    if (resultCode == Activity.RESULT_OK && requestCode == PICK_CONTACT_REQUEST) {
        // Obtenemos el nombre del contacto
        Cursor cursor = getContentResolver().query(data.getData(),
        new String[] {Contacts.DISPLAY_NAME}, null, null, null);
        if (cursor.moveToFirst()) { // true si el cursor no está vacío
            int columnIndex = cursor.getColumnIndex(Contacts.DISPLAY_NAME);
            String name = cursor.getString(columnIndex);
            // Hacemos algo con el nombre del contacto ...
        }
    }
}

Desde algún lugar de nuestra actividad, llamaremos al método pickContact() que será el encargado de realizar la petición a la agenda de contactos. El sistema procesa la petición en función de la acción y el URI especificados, abriendo la actividad adecuada de la agenda de contactos. La agenda mostrará un listado de los contactos a la espera de que el usuario seleccione uno para devolverlo como resultado (pick). Desde nuestra actividad, obtenemos el contacto seleccionado desde el método onActivityResult() y lo procesamos.

Interrumpiendo nuestra actividad.

Podremos interrumpir la ejecución de una actividad llamando a su método finish(). También podremos interrumpir la ejecución de una actividad desde otra actividad llamando al método finishActivity().

Nota. Interrumpir una actividad de esta manera no es lo habitual. Como norma, será el sistema Android el que se encargue de gestionar el ciclo de vida de nuestras actividades por nosotros, aunque hay determinadas situaciones en las que nos veremos obligados a saltarnos esta regla.

Ciclo de vida de nuestra actividad.

Gestionar el ciclo de vida de las actividades implementado sus métodos retrollamada es crucial para el desarrollo de aplicaciones robustas y flexibles en Android. El ciclo de vida de una actividad dependerá: de la relación con el resto de actividades, de su propia tarea y de la pila de retroces (back stack).

Una actividad puede estar durante un tiempo prolongado en alguno de los estados siguientes:
Reanudada.
La actividad se muestra en primer plano y el usuario puede interactuar con ella. En ocasiones a este estado también se le puede llamar en ejecución.
Pausada (o en pausa).
Aún se puede ver la actividad mientras otra actividad pasa a primer plano y obtiene el foco. Nuestra actividad aún se sigue visualizando aunque cuente con otra actividad por encima de ella que es semi transparente, o bien, no ocupa toda la pantalla. Una actividad en pausa se encuentra viva (su objeto Activity aún reside en memoria, mantiene su estado y permanece unida al gestor de ventanas), pero puede ser destruida por el sistema en situaciones en las que la memoria sea escasa.
Detenida.
La actividad pasa a estar oculta en su totalidad por otra actividad, pasando a un segundo plano. Una actividad detenida está aún viva (su objeto Activity aún sigue en memoria, conserva su estado pero ya no está unida al gestor de ventanas). Sin embargo, no será visible al usuario y puede ser destruida por el sistema en situaciones en las que la memoria sea necesaria por otras actividades.

Si una actividad está en pausa o detenida, el sistema podrá borrarla de la memoria ya sea porque le envía una señal para que finalice, o porque la elimina directamente. Cuando la actividad se reanuda por alguno de estos motivos, tendremos que volver a crearlo todo desde el principio.

Implementando los métodos retrollamada.

Cada vez que una actividad cambia de estado (reanudada, pausada, detenida), el sistema nos avisará invocando uno de los métodos retrollamada asociados a la misma. Podremos sobreescribir estos métodos con nuestro propio código. Por ejemplo:
public class ExampleActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // La actividad está siendo creada.
    }
    @Override
    protected void onStart() {
        super.onStart();
        // La actividad está a punto de hacerse visible.
    }
    @Override
    protected void onResume() {
        super.onResume();
        // La actividad se ha hecho visible y está reanudada (en ejecución).
    }
    @Override
    protected void onPause() {
        super.onPause();
        // Otra actividad está tomando el foco (esta actividad está a punto de entrar en pausa).
    }
    @Override
    protected void onStop() {
        super.onStop();
        // La actividad ya no es visible y ahora está detenida.
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        // La actividad está a punto de ser destruida.
    }
}
Nota. Cuando vayas a sobreescribir cualesquiera de estos métodos, lo primero que tendrás que hacer es llamar al método de la clase padre correspondiente, como se muestra en el ejemplo.

El orden en el que estos métodos son invocados, definen el ciclo de vida de nuestra actividad. Dentro de éste, podemos observar tres ciclos más internos:
  • Ciclo completo de la actividad que estaría comprendido entre la invocación de los métodos onCreate() y onDestroy(), es decir, el ciclo completo. La actividad debería usar el método onCreate() para realizar operaciones de ámbito global tales como definir la plantilla, y por otro lado, el método onDestroy() liberar ciertos recursos. Por ejemplo, si la actividad cuenta con alguna hebra ejecutándose en segundo plano para descargarse algún contenido desde la red, deberíamos crear hebra en el método onCreate() y eliminarla en el método onDestroy().
  • Ciclo de visibilidad que estaría comprendido entre la invocación de los métodos homólogos onStart() y onStop(). Durante este tiempo el usuario puede ver la actividad en pantalla e interactúa con ella. Por ejemplo, el método onStop() es llamado cuando una actividad nueva se inicia y oculta por completo nuestra actividad. Entre estos dos métodos, deberíamos mantener recursos que son necesarios para mostrar la actividad al usuario. Por ejemplo, podríamos activar y desactivar las animaciones de la interfaz del usuario. El sistema llamará a ambos métodos varias veces a lo largo de la vida de la actividad, tantas veces como la actividad se muestre y se oculte al usuario.
  • Ciclo de primer plano que estaría comprendido entre la invocación de los métodos homólogos onResume() y onPause(). Durante este tiempo, nuestra actividad se mostrará por encima de todas las demás y el usuario podrá interactuar con ella. Una actividad transitará varias veces entre estar o no en primer plano. Por ejemplo, el método onPause() será invocado cuando el dispositivo pase a estar en modo reposo o cuando se muestre un cuadro de diálogo. Debido a que esta transición se hará muy a menudo, el código que escribamos en estos métodos deberá minimizar el uso de recursos al mínimo para evitar transiciones lentas que hagan esperar al usuario.

La imagen 1 muestra estos ciclos y los caminos que una actividad puede seguir entre estados. Los rectángulos representan los métodos retrollamada asociados a la actividad.

Ciclo de vida de una actividad
Imagen 1. Ciclo de vida de una actividad.

En la siguiente tabla resumen describimos los métodos retrollamada asociados a los cambios de estado de una actividad. Observa las identaciones de la primera columna y asócialas con el emparejamiento de métodos homólogos del sub ciclo correspondiente:

Método Descripción Se puede eliminar Siguiente
onCreate() Se llama cuando la actividad se crea por primera vez. Es el lugar donde deberíamos configurar: vistas, enlazar datos con listas, etc. A este método se le pasa como argumento un objeto Bundle que almacena el estado previo de la actividad en el caso de haber sido eliminada de la memoria por el sistema previamente. No onStart()
    onRestart() Se llama cuando la actividad ha sido detenida, justo antes de volver a ser iniciada. No onStart()
    onStart() Se llama justo antes de mostrar la actividad al usuario. Seguida por onResume() si la actividad entra en primer plano, o por onStop() si ésta se interrumpe y se oculta. No onResume(), onStop()
        onResume() Se llama antes de que la actividad pase a interactuar con el usuario. En este momento la actividad se encontraría en el tope de la pila de retroceso. No onPause()
        onPause() Se llama cuando el sistema reanuda otra actividad. Este método se utiliza para guardar los cambios de datos persistentes, parar animaciones, etc. Estas operaciones deberían de ser rápidas debido a que la nueva actividad no será reanudada hasta que este método termine. A continuación se llamará al método onResume() si la actividad vuelve al primer plano, o se llamará al método onStop() si empieza a ocultarse al usuario. Si onResume(), onStop()
    onStop() Se llama cuando la actividad ya no es visible al usuario. Esto sucede debido a que se ha eliminado o porque otra actividad ha sido reanudada. Seguido por onRestart() si la actividad vuelve para interactuar con el usuario, o onDestroy() si la actividad se elimina. Si onRestart(), onDestroy()
onDestroy() Se llama antes de que la actividad sea eliminada. Esta es la última llamada que una actividad puede recibir. El método se invoca tanto si se ha llamado el método finish() desde la propia actividad, como si el sistema elimina la actividad por falta de memoria. Podemos distinguir ambos casos utilizando el método isFinishing(). Si ninguno

La columna "SE PUEDE ELIMINAR", significa si el sistema puede eliminar o no el proceso de la actividad una vez ha finalizado el método y sin previo aviso. Tres son los métodos desde los cuales el  sistema podría eliminar el proceso de nuestra aplicación: onPause(), onStop() y onDestroy(). Al ser onPause() el primero en ser invocado en la secuencia de llamadas (ver imagen 1), tendremos la garantía de que su código siempre será ejecutado antes de que el sistema elimine el proceso en caso de necesidad. El método onStop() y onDestroy() puede que no lleguen a ejecutarse. Por lo tanto, usaremos onPause() para la persistencia de datos.

Los métodos que tienen un "No" en la columna "SE PUEDE ELIMINAR" se ejecutarán sin que el sistema pueda eliminar su proceso. Por lo tanto, el proceso de una actividad podrá ser eliminado por el sistema una llame al método onPause() y mientras no se llame al método onResume().

Nota. Teóricamente una actividad no puede ser eliminada por el sistema si éste ha invocado alguno de los métodos siguientes: onCreate(), onStart(), onRestart() y onResume(), pero pueden darse circunstancias de emergencia en las que esto no se cumpla.

Guardando el estado de la actividad.

Anteriormente se hizo una breve mención a cómo se almacenaba el estado de la actividad cuando ésta pasaba a estar pausada o detenida. Esto es cierto porque el objeto de la actividad aún reside en memoria cuando ésta es pausada o detenida y toda la información referente a sus miembros y estado actual aún se encuentran vivos. Por lo tanto, cualquier cambio que realice el usuario dentro de la actividad permanecerá y estará disponible cuando ésta se vuelva a reanudar.

Sin embargo, cuando el sistema elimina una actividad para conseguir memoria, el objeto asociado a la actividad se destruye, y el sistema no podrá reanudarla a partir de su estado previo porque ésta habrá dejado de existir. En su lugar, el sistema tendrá que restaurar la actividad si el usuario vuelve a ella. Para el usuario será transparente que la actividad sea eliminada y reconstruida y solo espera que la actividad esté tal cual la dejó cuando vuelva a ella. En esta situación, podemos garantizar que el estado de la actividad se conserve implementando el mecanismo necesario en un método retrollamada nuevo: onSaveInstanceState().

El sistema invoca el método onSaveInstanceState() antes de que la actividad sea susceptible de ser eliminada. El sistema pasa a este método un objeto Bundle en el que podremos almacenar información relacionada con el estado de la actividad a modo de pares clave-valor y usando métodos tales como putString() y putInt(). Si el sistema elimina el proceso de nuestra aplicación y el usuario vuelve a la actividad, el sistema recrea la actividad y pasa el Bundle tanto a los métodos onCreate() como al método onRestoreInstanceState(). Puedes usar cualquiera de los dos métodos para recuperar la información almacenada en el objeto Bundle. Éste estará vacío (null), cuando la actividad se crea por primera vez:

Imagen 2. En el camino de la derecha observamos cómo el estado de la actividad no se pierde y se recupera tal cual se había dejado. Sin embargo, por el camino de la izquierda, la actividad ha sido eliminada por el sistema y necesitamos implementar los mecanismos necesarios para restaurar el estado de la actividad.
Nota. No ha garantías de que onSaveInstanceState() sea llamada justo antes de que una actividad sea destruida. Hay casos en los cuales no será necesario guardar el estado de la actividad (cuando el usuario sale de la actividad pulsando el botón de retroceso, por ejemplo). Si el sistema llama al método onSaveInstanceState(), lo hace antes del método onStop() y probablemente antes del método onPause().

Sin embargo, si no necesitásemos implementar nada en el método onSaveStateInstance(), por defecto, parte del estado de una actividad será restaurado. Más específicamente, estamos hablando de la información referente a las vistas de la interfaz del usuario. Por ejemplo: EditText guarda el texto que haya sido introducido por el usuario, CheckBox guarda sus marcas, etc. Para que esto funcione de la manera correcta, tendremos que especificar un identificador (atributo android:id) a cada una de las vistas (widgets). Si un widget no tiene su identificador, no se guardará información relacionada a su estado.

Aunque la implementación por defecto del método onSaveInstanceState() guarda información útil referente a controles de la interfaz del usuario, deberíamos sobreescribirlo para guardar información extra. Por ejemplo, guardar información de variables miembro que cambian a lo largo de la vida de la actividad.

Nota. Puedes desactivar el mecanismo por defecto que guarda información de estado referente a controles de la interfaz. Para ello puedes especificar el atributo android:saveEnabled="false" o bien puedes llamar al método setSaveEnabled(false). En la mayoría de los casos no tendremos que hacerlo, pero si lo hacemos, tendremos que implementar nuestro propio mecanismo de recuperación de estado para la interfaz.

Nota. Debido a que no hay garantías de que el método onSaveInstanceState() sea invocado, deberíamos usarlo solo para guardar datos dinámicos de la actividad. Nunca lo uses para almacenar información persistente. Para éste último caso, utiliza el método onPause().

Una buena manera de probar la capacidad de nuestra actividad para restaurar su estado es cambiando la orientación de pantalla del dispositivo. Cuando la orientación cambia, el sistema destruye la actividad y la vuelve a restaurar con el objetivo de cargar nuevos recursos asociados a la nueva configuración de pantalla. Solo por esta razón, es importante que nuestra actividad restaure su estado por completo porque es muy habitual que los usuarios cambien la orientación de pantalla mientras usan aplicaciones.

Gestionando cambios de configuración.

Algunas configuraciones de dispositivo pueden cambiar en tiempo de ejecución (orientación de la pantalla, disponibilidad del teclado, idioma, etc). Cuando alguno de esos cambios sucede, Android restaura la actividad que se está ejecutando (el sistema llama su método onDestroy() seguido del método onCreate(). Este comportamiento esta hecho para que la aplicación se adapte a la nueva configuración automáticamente cargándose los recursos alternativos que le proporcionemos (plantillas diferentes para orientaciones y tamaños de pantalla diferentes, por ejemplo).

Diseñar de la manera apropiada nuestras actividades, siendo éstas capaces de recuperarse ante este tipo de cambios, hace que nuestra aplicación sea más robusta y que se comporte mejor ante acontecimientos inesperados.

Sincronizando nuestras actividades.

Cuando una actividad inicia otra actividad, ambas experimentan cambios de estado en sus respectivos ciclos de vida. La primera actividad entra en pausa y posteriormente se detiene cuando la segunda actividad se crea. En el caso en el que ambas actividades compartan datos que guardan en el disco o en algún otro lugar, es importante comprender que la primera actividad no será completamente parada cuando la segunda empieza a ser creada. Más bien, el proceso que inicia la segunda se superpone con el proceso que para a la primera.

Si las dos actividades pertenecen al mismo proceso, el orden de ejecución de las retrollamadas será el correcto:
  1. El método onPause() de la primera actividad se ejecuta.
  2. Los métodos onCreate(), onStart() y onResume() se ejecutarán secuencialmente. La segunda actividad pasa a tener el foco (el usuario pasa interactuar con ella).
  3. Si la primera actividad no puede verse en la pantalla, se ejecuta su método onStop().

Esta secuencia de llamadas nos permitirá gestionar el intercambio de información entre una actividad y otra. Por ejemplo, si tenemos que escribir en una base de datos cuando la primera actividad se detiene, entonces tendríamos que escribir la información en el método onPause() para que ésta se encuentre disponible en la segunda actividad.

No hay comentarios:

Publicar un comentario