Iniciando una actividad

A diferencia de otros paradigmas de programación en los que las aplicaciones se lanzan con un método main(), el sistema Android inicia el código de una instancia de Activity invocando métodos específicos de retrollamada que se corresponden con etapas específicas de su ciclo de vida. Hay una secuencia de métodos de retrollamada que inician una actividad y una secuencia de métodos de retrollamada que destruyen una actividad.

Esta lección proporciona una visión general de los métodos de ciclo de vida más importantes y muestra cómo manejar la primera retrollamada del ciclo de vida, que crea una nueva instancia de tu actividad.

Entender las retrollamadas de ciclo de vida


A lo largo de la vida de una actividad, el sistema llama a un conjunto de métodos de ciclo de vida en una secuencia similar a una pirámide escalonada. Esto es, cada etapa del ciclo de vida de la actividad es un escalón distinto de la pirámide. En el proceso de crear una nueva instancia de una actividad, cada método de retrollamada mueve el estado de la actividad un escalón hacia la cima de la pirámide. La cima de la pirámide es el punto en el cuál la actividad se encuentra corriendo en primer plano y el usuario puede interactuar con ella.

Cuando el usuario empieza a abandonar la actividad, el sistema llama a otros métodos que mueven el estado de la actividad de vuelta a la base de la pirámide para desmantelarla. En algunos casos, la actividad sólo se moverá a un punto intermedio de la pirámide y esperará (como cuando el usuario cambia a otra aplicación), desde este punto la actividad puede volver a la cima (si el usuario vuelve a la actividad) y reanudar su funcionamiento desde donde el usuario la había dejado.

Figura 1. Ilustración simplificada del ciclo de vida de una actividad, expresada como una pirámide escalonada. Esta imagen muestra cómo para cada retrollamada utilizada para mandar la actividad un paso hacia el estado de reanudada en la cima, hay un método de retrollamada que mueve la actividad un escalón hacia abajo. La actividad también puede volver al estado de reanudada desde los estados de pausada y parada.

Dependiendo de la complejidad de tu actividad, probablemente no necesites implementar todos los métodos de ciclo de vida. Sin embargo, es importante que entiendas cada uno de ellos y que implementes todos los necesarios para asegurar que tu aplicación se comporta en la forma que los usuarios esperan. Implementar los métodos de ciclo de vida de la actividad correctamente asegura que tu aplicación se comportará de forma apropiada, incluyendo que:

  • No falle si el usuario recibe una llamada de teléfono o cambia a otra aplicación mientras usa tu aplicación.
  • No consuma recursos del sistema cuando el usuario no está utilizándola.
  • No pierda el progreso del usuario si deja la aplicación y vuelve a ella posteriormente.
  • No falle o pierda el progreso del usuario cuando la pantalla rote entre apaisado y retrato.

Como aprenderás en las próximas lecciones, hay distintas situaciones en las que la actividad transiciona entre los distintos estados que se ilustran en la figura 1. Sin embargo, sólo tres de estos estados son estáticos. Esto es, sólo hay tres estados en los que la actividad se puede mantener durante un periodo largo de tiempo:

Reanudada
En este estado, la actividad está en primer plano y el usuario puede interactuar con ella. (Estado también llamado a veces "ejecutando".)
Pausada
En este estado, la actividad está parcialmente oculta por otra actividad—la actividad que está en primer plano es semitransparente o no cubre toda la pantalla. La actividad pausada no recibe la entrada del usuario y no puede ejecutar ningún código.
Parada
En este estado, la actividad está completamente oculta y no es visible para el usuario; se considera que está en segundo plano. Mientras está parada, se conserva la instancia de la actividad y toda su información de estado, como variables miembro, pero no puede ejecutar ningún código.

Los otros estados (Creada e Iniciada) son transitorios y el sistema pasa rápidamente a los siguientes llamando al correspondiente método de retrollamada del ciclo de vida. Esto es, después de que el sistema llama a onCreate(), se llama rápidamente a onStart(), a lo que le sigue una rápida llamada a onResume().

Eso es todo en lo que respecta a los fundamentos del ciclo de vida de la actividad. Ahora empezarás a aprender acerca de algunos comportamientos específicos del ciclo de vida.

Especificar la actividad lanzadora de tu aplicación


Cuando el usuario selecciona el icono de tu aplicación en la pantalla de Inicio, el sistema llama al método onCreate() de la Activity de tu aplicación que hayas declarado como actividad "lanzadora" (o "principal"). Esta es la actividad que sirve como punto de entrada principal para la interfaz de usuario de tu aplicación.

Puedes definir qué actividad usar como actividad principal en el archivo de manifiesto, AndroidManifest.xml, situado en el directorio raíz de tu proyecto.

La actividad principal de tu aplicación debe declararse en el manifiesto con un <intent-filter> que incluya la acción MAIN y la categoría LAUNCHER. Por ejemplo:

<activity android:name=".MainActivity" android:label="@string/app_name">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

Nota: Cuando creas un nuevo proyecto Android con las herramientas del SDK, los archivos por defecto del proyecto incluyen una clase Activity que se declara en el manifiesto con este filtro.

Si no se declara la acción MAIN y la categoría LAUNCHER para alguna de las actividades, entonces el icono de la aplicación no se mostrará en la lista de aplicaciones de la pantalla de Inicio.

Crear una nueva instancia


La mayoría de las aplicaciones incluyen varias actividades distintas que permiten al usuario llevar a cabo distintas acciones. Ya se trate de la actividad principal creada cuando el usuario pulsa sobre el icono de tu aplicación o una actividad distinta que tu aplicación inicie en respuesta a una acción del usuario, el sistema crea cada nueva instancia de Activity llamando a su método onCreate().

Debes implementar el método onCreate() para llevar a cabo la lógica de arranque básico de tu aplicación; aquella que sólo debería ocurrir una vez en toda la vida de la actividad. Por ejemplo, tu implementación de onCreate() debería definir la interfaz de usuario y posiblemente instanciar algunas variables de ámbito de clase.

El siguiente ejemplo del método onCreate() muestra un código que lleva a cabo la configuración básica de la actividad, como la declaración de la interfaz de usuario (definida en un archivo XML de diseño), definición de variables miembro, y configuración de parte de la interfaz de usuario.

TextView mTextView; // Variable miembro para la vista de texto en el diseño

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

    // Establece la interfaz de usuario para esta Activity
    // La interfaz está definida en el archivo res/layout/main_activity.xml
    setContentView(R.layout.main_activity);
    
    // Inicializa el TextView miembro para que podamos manipularlo después
    mTextView = (TextView) findViewById(R.id.text_message);
    
    // Si estamos en Honeycomb o superior podemos usar las APIs de ActionBar
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        // Para la actividad principal, nos aseguramos de que el icono de la
        // aplicación de la barra de acciones no se comporte como un botón
        ActionBar actionBar = getActionBar();
        actionBar.setHomeButtonEnabled(false);
    }
}

Precaución: El uso de SDK_INT para prevenir que versiones anteriores ejecuten APIs nuevas sólo funciona de esta forma en Android 2.0 (nivel API 5) y superior. En versiones anteriores este código generaría una excepción en tiempo de ejecución.

Una vez que onCreate() termina su ejecución, el sistema llama a los métodos onStart() y onResume() en rápida sucesión. Tu actividad nunca se mantendrá en los estados de Creada o Iniciada. Técnicamente, la actividad se hace visible para el usuario cuando se llama a onStart(), pero onResume() le sigue rápidamente y la actividad se mantiene en el estado de Reanudada hasta que ocurre algo que lo cambie, como el que se reciba una llamada de teléfono, que el usuario navegue a otra actividad, o que la pantalla del dispositivo se apague.

En lecciones posteriores veremos cómo usar onStart() y onResume() para reanudar la actividad desde los estados de Pausada o Parada.

Nota: El método onCreate() incluye un parámetro llamado savedInstanceState que se trata en mayor profundidad en la lección Recreando una actividad.

Figura 2. Otra ilustración de la estructura del ciclo de vida de la actividad, esta vez con énfasis en las tres retrollamadas principales que el sistema ejecuta secuencialmente cuando se crea una nueva instancia de una actividad: onCreate(), onStart(), y onResume(). Una vez esta secuencia de retrollamadas se completa, la actividad alcanza el estado de Reanudada, en el que los usuarios pueden interactuar con la actividad hasta que cambian a otra actividad distinta.

Destruir la actividad


Si la primera retrollamada del ciclo de vida de la actividad es onCreate(), la última retrollamada es onDestroy(). El sistema llama a este método de tu actividad como señal última de que está siendo completamente eliminada de la memoria del sistema.

La mayoría de las aplicaciones no necesitan implementar este método porque las referencias locales de las clases se destruyen con la actividad y tu actividad debería llevar a cabo la mayor parte de su limpieza durante onPause() y onStop(). Sin embargo, si creaste hilos en segundo plano en onCreate() o tu actividad utiliza otros recursos de larga duración que pudieran, potencialmente, producir fugas de memoria de no cerrarse correctamente, deberías matarlos en onDestroy().

@Override
public void onDestroy() {
    super.onDestroy();  // Llama siempre a la super clase
    
    // Detiene la traza de métodos que iniciamos en onCreate()
    android.os.Debug.stopMethodTracing();
}

Nota: El sistema llama a onDestroy() después de haber llamado a onPause() y onStop() en todas las situaciones excepto en una: cuando se llama a finish() desde el método onCreate(). En algunos casos, por ejemplo si tu actividad se utiliza para lanzar otra actividad, puedes llamar a finish() desde onCreate() para destruir la actividad. En este caso, el sistema llama inmediatamente a onDestroy() sin llamar a ninguno de los otros métodos de ciclo de vida.