intive Argentina Blog

EventBus: una alternativa al BroadcastReceiver

Para no abusar de una herramienta es bueno entender su finalidad. Para ello, antes de explicar de qué se trata el protagonista de este artículo, el EventBus, es preciso aclarar algunas nociones.

Siempre que se desee desarrollar una app para un Android OS se deben tener en cuenta dos cuestiones básicas:

  1. JAVA es el lenguaje utilizado a la hora de programar.
  2. Se trabaja con una SDK propia de la plataforma que, a grandes rasgos, posee cuatro pilares: Activity, Service, BroadcastReceiverContentProvider.

Una Activity es el medio para interactuar con el usuario. Por lo general, se crea una por cada pantalla que integra la aplicación. Si la app trata, por ejemplo, de un gestor de correos, probablemente se tenga una Activity para escribir un nuevo email y otra distinta para visualizar la bandeja de entrada.

En cambio, el Service no posee interacción con el usuario y tiene como fin realizar tareas»largas» en background. Dado que Android OS permite trabajar con distintos threads, se recomienda no sobrecargar el main thread con tareas que le impidan al usuario interactuar de modo ágil con la aplicación. Un ejemplo nos hará ver las cosas de un modo más simple:

Supongamos que tenemos un reproductor de audio. El usuario siempre deberá tener la posibilidad de cambiar de track, no importa si en ese momento se reproduce un track distinto al deseado. Por lo tanto, el thread principal va a mostrar por pantalla el menú que el usuario va a utilizar para reproducir distintos tracks, mientras que un Service, corriendo en background, reproducirá el track seleccionado.

Detallado lo anterior surge un duda: ¿cómo comunicar Activities entre sí, o una Activity con un Service?

  • Cómo comunicar Activities entre sí: en el primero de los dos casos hay que tener en cuenta que sólo se puede tener una Activity corriendo en tiempo de ejecución. Siempre habrá una sola que tendrá a cargo el main thread y, por lo tanto, interactuará con el usuario. Ahora, cuando una Activity cumplió su razón de existir y es hora de pasar a la siguiente, suele presentarse la necesidad de pasarle datos a esa próxima. Por lo tanto, la SDK disponible nos da una mano grande, al acercarnos el Intent. Éste nos permite decirle al OS cuál es la siguiente Activity y adjuntarle información extra. Teniendo en cuenta que se trata de JAVA y programación orientada a objetos, cualquier instancia puede adjuntarse y recibirse a través de un Intent, siempre y cuando implemente una simple interfaz: Parcelable.

Ahora nos encontramos con el caso de que una Activity lanza un Service, para lo que necesita brindarle datos. En este caso, el procedimiento es casi idéntico al anterior, ya que haciendo uso de un Intent se le ordena al OS iniciar un servicio en background, adjuntándole los datos al Intent. La vuelta podría ser igual de sencilla, pero no lo es. Recordemos, entonces:

  1. el Service corre en un thread distinto al main thread.
  2. un Service podría ser lanzado por una Activity A y precisar que el mismo interactúe con una B y una C.

Entonces, ¿cómo puede saber el Service cuál es la Activity que en la actualidad está teniendo lugar? Simple: la SDK nos brinda una herramienta llamada LocalBroadcastManager que, básicamente, publica Intents para que sus suscriptores puedan recibirlos en tiempo de ejecución. A esta altura es fácil describir el BroadcastReceiver, ya que se trata de una clase abstracta que, al extenderla, detallamos qué tipo de Intents esperamos recibir y qué hacer en caso de recibir uno.

A esta altura ya se tiene alguna noción para entender cuál es el fuerte de la herramienta que este artículo quiere presentar: el EventBus.

 

¿Cuándo debería tener en cuenta el uso de Event Bus?

Cuando se hace uso de un Service para realizar distintas tareas y se espera un feedback del mismo, es importante notar que genera un Intent de un determinado tipo (customizable) y -luego de adjuntarle la información correspondiente al resultado del procesamiento de dicha tarea- lo publica haciendo uso del LocalBroadcastManager, para ser recibido por la Activity en espera que contiene el correspondiente BroadcastReceiver. Se debe tener en cuenta que los BroadcastReceivers, a través de los intents-filters declarados en el Manifest, determinan que tipo de Intents deben ser notificados.

Ahora bien, un mismo Service puede devolver diferentes tipos de Intents con distintas clases de datos adjuntos, siendo el BroadcastReceiver el encargado de decodificar esos datos según de qué Intent se trate. Es por esto que el BroadcastReceiver debe ser lo suficientemente inteligente como para entender de qué tipo de Intent se trata, para luego hacer una correcta decodificación de los datos adjuntos. Cuando la aplicación escala, esto se puede volver engorroso, ya que habría que extender la clase BroadcastReceiver cada vez que se quiera hacer uso de un nuevo tipo de Intent.

Acá nace EventBus, en reemplazo del LocalBroadcastManager, y permitiendo a cualquier Activity registrarse al mismo de una manera muy sencilla, para luego implementar un callback por cada tipo de Event del que se quiera tener control. Por ende, el Service una vez finalizado el procesamiento crea un Event resultante y lo envía al EventBus el cual se encarga de analizar si la Activity en ejecución está suscripta y en caso de estarlo y de tener un callback específico para dicho tipo de Event ejecutarlo.

La ventaja reside en que ya no se necesita extender la clase BroadcastReceiver, ni modificar el Manifest acorde a esto, sino que sólo se crean Events y callbacks para los mismos dentro de las Activities, lo cual es mucho más legible y sencillo de implementar.

Un ejemplo:

  • Implementación de Eventos. Esto es parte del modelo que se desee implementar. Las instancias de estas clases contendrán la información que se desee comunicar a lo largo de la app.

 

  • Suscripción de la Activity al EventBus. Observar que se puede implementar un onEvent method por cada tipo de evento que se quiera recibir.

  • Post de eventos. Esto puede realizarse desde un Service por ejemplo. De esta manera todas las activities suscritas recibirían los mensajes que se envíen del mismo, que tranquilamente puede correr en background.

 

Pablo Gotuzzo

Trabaja como desarrollador de Java en la compañía. Integra la brigada Android, para la que investiga y produce contenido. Es estudiante de Ingeniería en Informática en la Universidad de Buenos Aires. Tiene particular interés por afrontar nuevos desafíos que involucren el trabajo en equipo y la integración de nuevas tecnologías.

Deja un comentario