La hoja de trucos animada del modo de lanzamiento de Android

Dic 20, 2018 – 6 min read

Antes de la API 11, solíamos mostrar las actividades de cada nueva página en la pantalla. Ahora, con Fragments y las herramientas de navegación de la API 28, es totalmente posible hacer una aplicación muy compleja con una sola actividad. Sin embargo, las actividades siguen siendo excelentes para dividir tu aplicación en etapas y procesos. Tal vez quieras dividir todo el marketing en una actividad, y tener la aplicación real en su propia actividad. Tal vez quieras una sección reservada para una característica, como un servicio de chat. Conocer los modos de lanzamiento de las actividades te ayuda a dividir mejor estos procesos de forma que tengan sentido para tus usuarios. Sentado en el trabajo, nunca pude recordar los modos de lanzamiento de la parte superior de mi cabeza, así que pensé que iba a escribir un blog sobre ello, animar algunos gifs para ilustrar los conceptos, y luego compartirlo con todo el mundo. Antes de hablar de los modos de lanzamiento, vamos a entender el papel de una tarea. Una tarea contiene una colección de actividades que se organizan en una pila llamada backstack. La primera actividad que se lanza en una tarea es la actividad raíz. Al pulsar el botón de retroceso en una actividad raíz no sólo se mata la actividad, sino que se mata la tarea, y posiblemente la aplicación.

Ahora vamos a sumergirnos en algunos modos de lanzamiento!

Digamos que tienes una tarea con una actividad raíz llamada Actividad A, y luego lanzas una nueva actividad llamada B, B se empuja a la parte superior de la pila. Ahora digamos que lanzas otra Actividad B desde la B que acabamos de crear, ahora tendrás dos instancias de la Actividad B apiladas una encima de la otra. Si un usuario presiona el botón de retroceso, volverá a otra instancia de la Actividad B. Esto podría ser muy confuso para el usuario. El apilamiento y la creación de actividades una encima de la otra, sin importar qué, se llama modo de lanzamiento estándar. Si no hay un modo de lanzamiento definido en el XML de la actividad en el manifiesto, la actividad utilizará el modo de lanzamiento estándar.

Ahora que vemos cómo el modo Estándar puede ser desconcertante para el usuario, podemos entender el modo de lanzamiento Single Top. Este modo de lanzamiento impide que diferentes instancias de las mismas actividades se apilen unas sobre otras. Digamos que la Actividad B es un single top. Podemos definir los modos de lanzamiento en el manifiesto así:

///AndroidManifest.xml
<application
...>
<activity android:name=".Activity_A">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity> <activity android:name=".Activity_B" android:launchMode="singleTop"/> <activity android:name=".Activity_C"/>
<activity android:name=".Activity_D"/>
</application>

Así que ahora si lanzas la actividad B desde la actividad B, en lugar de crear una nueva instancia de B y apilarla encima de la antigua B, la intención se pasa a la instancia actual de B. La única manera de tener dos instancias de la misma actividad en una tarea es lanzar una actividad diferente desde B, y luego crear B desde esa actividad. El concepto principal del modo de lanzamiento superior único es que no puedes tener dos instancias de la misma actividad apiladas una encima de la otra.

Si no quieres dos instancias de la misma actividad superior única en una tarea mientras usas el modo de lanzamiento superior único, puedes pasar la constante FLAG_ACTIVITY_CLEAR_TOP en tu intent. Para ilustrar lo que hace esto, digamos que tu pila de actividades es ABC (B sigue siendo single top). Si lanzas B desde C con FLAG_ACTIVITY_CLEAR_TOP, tu pila saltará hasta B y la intención se pasará a esa misma instancia de B.

// code example for passing the constant flag in your intentIntent intent = new Intent(this, Activity_B.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

El siguiente modo de lanzamiento se llama Tarea Única. En este modo de lanzamiento, establecemos que una actividad sólo puede pertenecer a una tarea en todas las tareas de la aplicación. Así que, de forma similar al comportamiento FLAG_ACTIVITY_CLEAR_TOP, si tu pila es ABC, y lanzas B (una única tarea) desde C, hacemos un pop hasta B, y pasamos la intención a esa instancia.

<activity android:name=".Activity_B" android:launchMode="singleTask"/>

¿Pero qué pasa si queremos que B esté en su propia tarea? Aquí es donde entra en juego la afinidad de tareas. La afinidad de tareas permite definir a qué tarea pertenece una actividad. Por defecto, una actividad tiene la misma afinidad de tarea que su actividad raíz. Con la afinidad de tareas, ahora podemos separar las actividades en diferentes tareas.

<activity android:name=".Activity_A"
android:taskAffinity="com.affinity.of.a">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity><activity android:name=".Activity_B"
android:launchMode="singleTask"
android:taskAffinity="com.affinity.of.b"
/>

Aquí, la Actividad A y la Actividad B tienen diferentes afinidades de tareas. Cuando A se crea en la tarea 1, C se lanza desde A. Por defecto, cada actividad tiene la misma afinidad que su raíz, por lo que seguimos en la tarea 1. Ahora B se lanza desde C. B tiene una afinidad de tarea diferente, por lo que ahora es la raíz de la Tarea 2, que pasa a primer plano. Si lanzamos una nueva instancia de la Actividad C desde B, C pertenece a la Tarea 2 porque esa es la afinidad de tarea de la actividad raíz (en este caso, B). ¿Pero qué pasa si ahora intentamos lanzar A desde C en la Tarea 2? Como la afinidad de A es la Tarea 1, cambiamos de la Tarea 2 a la Tarea 1, volvemos a la Actividad A, y finalmente pasamos la intención a A.

Conocer la Tarea Única nos ayudará a entender mejor el modo de lanzamiento final; Instancia Única. Al igual que la Tarea Única, una Actividad con Instancia Única puede ser la única Actividad en todas las tareas. La diferencia entre las dos es que una Actividad con Instancia Única también puede ser la única actividad en una tarea.

<activity android:name=".Activity_B"
android:launchMode="singleInstance"
android:taskAffinity="com.affinity.of.b"
/>

En este ejemplo, la Actividad B tendrá un modo de lanzamiento de Instancia Única. La actividad A en la tarea 1 lanza la actividad B. Esto hace que la actividad B se lance en una nueva tarea, que se pone en primer plano. La actividad B entonces lanza la actividad C. Dado que una instancia única puede ser la única actividad en una tarea, C se lanza encima de la actividad A en la tarea 1, y entonces la tarea 1 pasa a primer plano.

La afinidad de tareas también juega un papel en la instancia única. Si la Actividad B no tiene afinidad de tareas, un usuario no puede navegar de vuelta a la Tarea 1. Si B tuviera afinidad de tareas, un usuario podrá ir y venir entre la Tarea 1 y la 2.

Conocer los modos de lanzamiento me ayuda a hacer mejores experiencias de UI/UX para mis usuarios, e incluso me ayuda a resolver algunos bugs que me traen de cabeza, así que espero que esta información te ayude a ti también.

Quiero dar un saludo a la página de youtube CodeTutor de Anil Deshpande por ayudarme a entender mejor el concepto. Aquí está el primero de siete videos sobre este tema: https://www.youtube.com/watch?v=m8sf0UkJkxo

Deja un comentario