Introducción a las actividades

La clase Activity es un componente clave de una app para Android, y la forma en que se inician y se crean las actividades es una parte fundamental del modelo de aplicación de la plataforma. A diferencia de los paradigmas de programación en los que las apps se inician con un método main(), el sistema Android inicia el código en una instancia de Activity invocando métodos de devolución de llamada específicos que corresponden a etapas específicas de su ciclo de vida.

En este documento, se introduce el concepto de actividades y se proporciona una guía simple sobre cómo trabajar con ellas. A fin de obtener información adicional sobre las prácticas recomendadas para diseñar la arquitectura de tu app, consulta la Guía de arquitectura de apps.

El concepto de actividades

La experiencia con la app para dispositivos móviles difiere de la versión de escritorio, ya que la interacción del usuario con la app no siempre comienza en el mismo lugar. En este caso, no hay un lugar específico desde donde el usuario comienza su actividad. Por ejemplo, si abres una app de correo electrónico desde la pantalla principal, es posible que veas una lista de correos electrónicos. Por el contrario, si usas una app de redes sociales que luego inicia tu app de correo electrónico, es posible que accedas directamente a la pantalla de la app de correo electrónico para redactar uno.

La clase Activity está diseñada para facilitar este paradigma. Cuando una app invoca a otra, la app que realiza la llamada invoca una actividad en la otra, en lugar de a la app en sí. De esta manera, la actividad sirve como el punto de entrada para la interacción de una app con el usuario. Implementas una actividad como una subclase de la clase Activity.

Una actividad proporciona la ventana en la que la app dibuja su IU. Por lo general, esta ventana llena la pantalla, pero puede ser más pequeña y flotar sobre otras ventanas. Generalmente, una actividad implementa una pantalla en una app. Por ejemplo, una actividad de una app puede implementar una pantalla Preferencias mientras otra implementa una pantalla Seleccionar foto.

La mayoría de las apps contienen varias pantallas, lo cual significa que incluyen varias actividades. Por lo general, una actividad en una app se especifica como la actividad principal, que es la primera pantalla que aparece cuando el usuario inicia la app. Luego, cada actividad puede iniciar otra actividad a fin de realizar diferentes acciones. Por ejemplo, la actividad principal de una app de correo electrónico simple podría proporcionar una pantalla en la que se muestra una casilla de correo electrónico. A partir de aquí, la actividad principal podría iniciar otras actividades que proporcionan pantallas para tareas como redactar correos y abrir correos electrónicos individuales.

Si bien las actividades trabajan en conjunto a fin de crear una experiencia del usuario coherente en una app, cada actividad se relaciona vagamente con otras actividades; por lo general, hay una pequeña cantidad de dependencias entre las actividades de una app. De hecho, estas suelen iniciar actividades que pertenecen a otras apps. Por ejemplo, una app de navegador podría iniciar la acción de "Compartir actividad" de una app de redes sociales.

Si quieres usar actividades en tu app, debes registrar información sobre estas en el manifiesto de la app y administrar los ciclos de vida de las actividades de manera apropiada. En el resto de este documento, se presentan estos temas.

Cómo configurar el manifiesto

Para que tu app pueda usar actividades, debes declararlas, y también declarar algunos de sus atributos, en el manifiesto.

Cómo declarar actividades

Para declarar tu actividad, abre tu archivo de manifiesto y agrega el elemento <activity> como objeto secundario del elemento <application>. Por ejemplo:

    <manifest ... >
      <application ... >
          <activity android:name=".ExampleActivity" />
          ...
      </application ... >
      ...
    </manifest >
    

El único atributo obligatorio para este elemento es android:name, que especifica el nombre de la clase de la actividad. También puedes agregar atributos que definan las características de la actividad, como una etiqueta, un ícono o un tema de IU. Para obtener más información sobre estos y otros atributos, consulta la documentación de referencia sobre el elemento <activity>.

Nota: Una vez que publiques tu app, no deberías cambiar los nombres de las actividades. Si lo haces, se pueden romper algunas funcionalidades, como los accesos directos a las apps. Para obtener más información sobre los cambios que debes evitar luego de la publicación, consulta Elementos que no debes modificar.

Cómo declarar filtros de intents

Los filtros de intents son una función muy útil de la plataforma de Android. Estos proporcionan la capacidad de iniciar una actividad no solo en función de una solicitud explícita, sino también de una implícita. Por ejemplo, una solicitud explícita podría indicar al sistema que debe "Iniciar la actividad 'Enviar correo electrónico' en la app de Gmail". En cambio, una solicitud implícita le indica al sistema que debe "Iniciar una pantalla 'Enviar correo electrónico' en cualquier actividad que pueda realizar la tarea". Cuando la IU del sistema le pregunta al usuario qué app debe usar para realizar la tarea, ese es un ejemplo de un filtro de intent.

Para aprovechar esta función, declara un atributo <intent-filter> en el elemento <activity>. La definición de este elemento incluye un elemento <action> y, de manera opcional, un elemento <category> o <data>. Estos elementos se combinan para especificar el tipo de intent al que puede responder la actividad. Por ejemplo, en el siguiente fragmento de código, se muestra cómo configurar una actividad que envía datos de texto y recibe solicitudes de otras actividades para hacerlo:

    <activity android:name=".ExampleActivity" android:icon="@drawable/app_icon">
        <intent-filter>
            <action android:name="android.intent.action.SEND" />
            <category android:name="android.intent.category.DEFAULT" />
            <data android:mimeType="text/plain" />
        </intent-filter>
    </activity>
    

En este ejemplo, el elemento <action> especifica que esta actividad envía datos. La declaración del elemento <category> como DEFAULT permite a la actividad recibir solicitudes de inicio. El elemento <data> especifica el tipo de datos que puede enviar esta actividad. En el siguiente fragmento de código, se muestra cómo llamar a la actividad que se describe más arriba:

Kotlin

    val sendIntent = Intent().apply {
        action = Intent.ACTION_SEND
        type = "text/plain"
        putExtra(Intent.EXTRA_TEXT, textMessage)
    }
    startActivity(sendIntent)
    

Java

    // Create the text message with a string
    Intent sendIntent = new Intent();
    sendIntent.setAction(Intent.ACTION_SEND);
    sendIntent.setType("text/plain");
    sendIntent.putExtra(Intent.EXTRA_TEXT, textMessage);
    // Start the activity
    startActivity(sendIntent);
    
Si deseas que tu app sea independiente y que no permita que otras apps inicien sus actividades, no necesitas filtros de intents adicionales. Las actividades que no quieras que estén disponibles para otras aplicaciones no deben incluir filtros de intents, y puedes iniciarlas por medio de intents explícitos. Para obtener más información sobre cómo tus actividades pueden responder a los intents, consulta Intents y filtros de intents.

Cómo declarar permisos

Puedes usar la etiqueta <activity> del manifiesto para controlar qué apps pueden iniciar una actividad en particular. Una actividad superior no puede iniciar una actividad secundaria, a menos que ambas tengan los mismos permisos en su manifiesto. Si declaras un elemento <uses-permission> para una actividad principal, cada actividad secundaria debe tener un elemento <uses-permission>.

Por ejemplo, si tu app quiere usar una app hipotética llamada SocialApp para compartir una publicación en las redes sociales, SocialApp debe definir el mismo permiso que la app que la llama debe tener:

    <manifest>
    <activity android:name="...."
       android:permission=”com.google.socialapp.permission.SHARE_POST”

    />
    

Luego, para poder llamar a SocialApp, tu app debe tener el mismo permiso que se estableció en el manifiesto de SocialApp.

    <manifest>
       <uses-permission android:name="com.google.socialapp.permission.SHARE_POST" />
    </manifest>
    

Para obtener más información sobre los permisos y la seguridad en general, consulta Seguridad y permisos.

Cómo administrar el ciclo de vida de la actividad

A lo largo de su vida útil, una actividad pasa por varios estados. Para administrar las transiciones entre estados, debes usar una serie de devoluciones de llamadas. En las siguientes secciones, se presentan estas devoluciones de llamadas.

onCreate()

Debes implementar esta devolución de llamada, que se activa cuando el sistema crea tu actividad. Tu implementación debe inicializar los componentes esenciales de tu actividad. Por ejemplo, tu app debería crear vistas y vincular datos a listas aquí. Principalmente, este es el momento en el que debes llamar a setContentView() para definir el diseño de la interfaz de usuario de tu actividad.

Cuando onCreate() finaliza, la siguiente devolución de llamada siempre es onStart().

onStart()

Cuando se cierra onCreate(), la actividad pasa al estado Iniciada y se vuelve visible para el usuario. Esta devolución de llamada contiene los preparativos finales de la actividad para pasar al primer plano y convertirse en interactiva.

onResume()

El sistema invoca esta devolución de llamada justo antes de que la actividad comience a interactuar con el usuario. En este punto, la actividad es la primera de la pila de actividades y captura todo lo que el usuario ingresa. La mayor parte de la funcionalidad principal de una app se implementa en el método onResume().

La devolución de llamada onPause() siempre va después de onResume().

onPause()

El sistema llama a onPause() cuando la actividad pierde el foco y pasa al estado Detenida. Este estado se produce, por ejemplo, cuando el usuario presiona el botón Atrás o Recientes. Cuando el sistema llama a onPause() para tu actividad, significa que esta aún está parcialmente visible, pero, a menudo, indica que el usuario está saliendo de la actividad y que esta pronto pasará al estado Detenida o Reanudada.

Una actividad en estado Detenida puede continuar con la actualización de la IU si el usuario espera que esta acción ocurra. Entre los ejemplos de tal actividad, se incluye mostrar una pantalla de mapa de navegación o la reproducción de un reproductor multimedia. Incluso si estas actividades pierden el foco, el usuario espera que su IU continúe actualizándose.

No debes usar onPause() para guardar datos de la aplicación o del usuario, realizar llamadas de red o ejecutar transacciones de base de datos. Para obtener más información sobre cómo guardar datos, consulta Cómo guardar y restablecer el estado de la actividad.

Una vez que finalice la ejecución de onPause(), la siguiente devolución de llamada será onStop() o onResume(), dependiendo de lo que ocurra cuando la actividad pase al estado Detenida.

onStop()

El sistema llama a onStop() cuando la actividad ya no es visible para el usuario, lo cual puede ocurrir porque se está eliminando la actividad, porque se inicia una nueva o porque una ya existente pasa al estado Reanudada y cubre la actividad que se detuvo. En todos estos casos, la actividad detenida ya no está visible en absoluto.

La siguiente devolución de llamada que el sistema invoca puede ser onRestart() (si la actividad vuelve a interactuar con el usuario) o onDestroy() (si esta actividad finaliza por completo).

onRestart()

El sistema invoca esta devolución de llamada cuando una actividad en estado Detenida está por volver a iniciarse. onRestart() restaura el estado de la actividad desde el momento en que esta se detuvo.

Luego de esta devolución de llamada, siempre sigue onStart().

onDestroy()

El sistema invoca esta devolución de llamada antes de que se elimine una actividad.

Esta devolución de llamada es la última que recibe la actividad. onDestroy() suele implementarse a fin de garantizar que todos los recursos de una actividad se liberen cuando esta, o el proceso que la contiene, se elimina.

En esta sección, solo se proporciona una introducción a este tema. Para obtener un análisis más detallado del ciclo de vida de la actividad y sus devoluciones de llamadas, consulta El ciclo de vida de la actividad.