lunes, 22 de junio de 2020

Formas de programar el evento OnClick para objetos para Android

En Android Studio existen tres formas para programar los eventos de los objetos, utilizando java,  las cuales revisaremos en esta nota.......

Para definir las acciones al hacer clic en un boton se puede definir de 3 formas al programar para android:
  • Declarar el evento en el XML layout y el metodo en el activity.
  • Declarar el metodo y el evento en el activity.
  • Y por ultimo mediante DataBinding.
Android tiene más de una forma de trabajar los eventos de la interacción usuario-aplicación. Al considerar los eventos de tu interfaz, se busca capturar los eventos desde el objeto de vista específico con el que interactúa el usuario.

Entre las diversas clases de vista a usar para componer tu diseño, observarás varios métodos de atención de llamada públicos que pueden ser útiles para eventos de IU. Estos métodos son llamados por Android cuando la acción respectiva ocurre en ese objeto.

Por ejemplo, cuando tocamos una vista (un botón), se llama al método onTouchEvent() del objeto. Y para interceptar esto se debe extender la clase y reemplazar el método. Pero, extender todos los objetos de vista para manejar tal evento no sería práctico.
 
Por eso, la clase de vista también contiene varias opciones de interfaces anidadas con devoluciones de llamada que puedes definir más fácilmente, llamadas también  receptores de eventos, te permiten capturar la interacción del usuario con tu IU. Quizás en algún momento desees extender una clase de vista a fin de crear un componente personalizado.

PRIMER METODO

El primer metodo y la forma mas basic de programar manejador del evento click del boton, es agregando el "android:onClick" atributo en el elemento "Button" del layout  XML correspondiente a la vista. El valor para este atributo debe ser el mismo que el nombre del metodo que queremos llamar desde el evento clic del boton. En la actividad estará el metodo al que llamara el evento.

El metodo declarado debe tener exactamente el mismo nombre que se escriba en android:onClick. Especialmente debe cumplir con las siguientes condiciones:
  •    Ser publico
  •    Devolver void
  •    Definir una Vista como su unico parametro(esta sera la vista donde fue ejecutado)
USANDO ON CLIC LISTENNER

Tambien puedes declarar el manejador del evento click desde el programa en lugar de hacerlo en el layout XML. Esto sera necesario si se inicia el boton en tiempo de ejecución o si necesita declarar el comportamiento del click en la subclase de un Fragment.

Para programar el manejador del evento, debe crear un objeto View.OnClickListenner y asignarlo al boton, llamandolo en el setOnClickListener(View.OnClickListener).


 
RECEPTOR DE EVENTOS
 
Un receptor de eventos es una interfaz de clase View, contiene un solo método de devolución de llamada. A estos métodos los llamará el marco de trabajo Android cuando la vista (con la que se registró el receptor), sea iniciada por la interacción del usuario con el elemento de la IU.

Las interfaces de receptores de eventos, incluyen los siguientes métodos de devolución de llamada:

onClick()
Desde View.OnClickListener. Se llama a este método cuando el usuario toca el elemento (en el modo táctil), o selecciona el elemento con las teclas de navegación o la bola de seguimiento y presiona la tecla Intro o la bola de seguimiento adecuada.
onLongClick()
Desde View.OnLongClickListener. Se llama a este método cuando el usuario toca y mantiene presionado el elemento (en el modo táctil), o selecciona el elemento con las teclas de navegación o la bola de seguimiento y mantiene presionada la tecla Intro o la bola de seguimiento adecuada (durante un segundo).
onFocusChange()
Desde View.OnFocusChangeListener. Se llama a este método cuando el usuario navega hacia el elemento o sale de él utilizando las teclas de navegación o la bola de seguimiento.
onKey()
Desde View.OnKeyListener. Se llama a este método cuando el usuario se centra en el elemento y presiona o suelta una tecla física del dispositivo.
onTouch()
Desde View.OnTouchListener. Se llama a este método cuando el usuario realiza una acción calificada como un evento táctil, por ejemplo, presionar, soltar o cualquier gesto de movimiento en la pantalla (dentro de los límites del elemento).
onCreateContextMenu()
Desde View.OnCreateContextMenuListener. Se llama a este método cuando se crea un menú contextual (como resultado de un "clic largo" sostenido). Consulta la explicación sobre menús contextuales en la guía para desarrolladores 
Estos métodos son únicos para cada interfaz, para definir uno de estos, implementa la interfaz anidada en su actividad o defínela como una clase anónima. Luego, pasa una instancia de tu implementación al método View.set...Listener() respectivo. (Por ejemplo, llama a setOnClickListener() y pásale tu implementación de OnClickListener).

En el ejemplo siguiente, se muestra cómo registrar un receptor onClick para un botón.




Te puede parecer más conveniente implementar OnClickListener como parte de tu actividad. Esto evitará la carga extra de la clase y la asignación de objetos.

 

sábado, 20 de junio de 2020

Programando en hilos "android.os.networkonmainthreadexception"

Puse como titulo, un error que devuelve el desarrollo en android cuando intentamos hacer correr una rutina en el hilo principal, y no en un hilo secundario tal como nos sugieren las buenas practicas. Comencemos..

¿Qué es?

En ingles se escribe Thread y la traducción mas clara es "hilo" tambien en alguna referencia usan el termino "hebra", siendo la primera la mas común. Un hilo es un proceso ligero ó subproceso, una secuencia de tareas encadenadas muy pequeña que puede ser ejecutada por un sistema operativo.

Todo programador especialmente de aplicaciones Android, en algún momento necesita conocer sobre el manejo de hilos, y gestionarlos dentro de su aplicación.


Si tenemos un mobile, le damos click en el icono de una aplicación para que se abra, el dispositivo ya tiene otras aplicaciones abiertas, y abrirá una mas en un nuevo hilo, es así, que podríamos decir que cada aplicación es un hilo. Estos son independientes, es decir las aplicaciones, no deberían de afectar una a la otra, ahora entonces, cuando estamos en una aplicación vemos que tenemos cosas como descarga de imágenes, accesos a las bases de datos, etc.

Estas tareas normalmente tienen un problema: no sabemos cuanto tiempo van a tardar, de hecho corremos siempre el riesgo de que la tarea no se complete.

Pongamos el ejemplo de una aplicación descargando una imagen, con una conexión a internet lenta, el usuario al no ver que la imagen se muestra en su teléfono puede pensar que la aplicación no funciona o simplemente se quedó colgada, pero en realidad solo está tardando. Entonces, tenemos un problema ya que cada aplicación es un solo hilo y necesitamos el hilo para trabajar con la imagen y ya que esta tarea está pendiente no podremos avanzar. Los hilos nos ayudan a resolver estos problemas.

Por tanto se pueden crear tantos hilos sean necesarios, generalmente un hilo para cada tarea donde necesitemos correr éstos paralelamente. Existe una diferencia de opiniones entre si esto es una ventaja o desventaja al momento de programación por el tema de complejidad.

¿Cómo usar?


Una aplicación móvil bien hecha hoy en día crea un hilo para tareas como descargas, conexiones, etc. es así que la aplicacion no se cuelga esperando que se concluyan tareas que estén tomando tiempo. Los hilos también, nos permiten separar tareas complejas en tareas mas simples y concretas, ademas nos permite fallar y que esto no sea tan grave, se divide las tareas en hilos y si tenemos algún problema el impacto no es tan negativo.

La destrucción de hilos antiguos por nuevos es una característica que no deja realizar varias tareas a la vez (concurrentemente). Los distintos hilos de ejecución comparten recursos como espacio de memoria, archivos abiertos, caso de autenticación, etc. 

Esta técnica permite simplificar el diseño de una aplicación que debe llevar a cabo distintas funciones simultáneamente.


El main thread es el hilo principal del programa, donde esta los principales eventos que conectaran con otros modulos del programa, asi como las interfaces graficas.


Y en este, se arma la forma como consumiremos nuestros accesos a archivos, conexiones, recursos del dispositivo, etc etc. Esta parte de la mano de una arquitectura adecuada, nos ayudara a tener clara y mantenible nuestra aplicacion android.


Ejemplos:

Debemos seguir dos reglas:

    No bloquear el hilo principal.
    Todas las operaciones de interfaz gráfica se hacen en el hilo principal.

Android ofrece muchas maneras para crear y administrar hilos, y existen librerías de terceros que hacen que la gestión de hilos en Android sea mucha mas sencilla y agradable para el programador.

Las operaciones de red, y las llamadas a la base de datos, servicios web y la carga de algunos componentes (Ej. imágenes de internet), son ejemplos comunes de operaciones que uno como programador debe evitar hacerlo en el hilo principal.

Categoricemos los componentes de subprocesamiento en dos categorías:
  • Subprocesos adjuntos a una actividad / fragmento: estos subprocesos están vinculados al ciclo de vida de la actividad / fragmento y finalizan tan pronto como se destruya la actividad /fragmento.
  • Subprocesos que no estan adjuntos a una actividad / fragmento: estos subprocesos pueden seguir ejecutandose más allá de la duración de la actividad / fragmento (si corresponde ) de la que se generarón.

Android permite crear hilos o subprocesos adicionales, para ejecutar tareas de larga duración. Una vez terminada la tarea podemos regresar al hilo principal para actualizar la interfaz de usuario.

El la imagen de ejemplo, en el ciclo de vida de la aplicaicon, desde que se le da clic en su icono, se crea la aplicacion en su MainThread, (pero un nuevo hilo para el S.O. android del celular), el cliclo de vida del hilo principal esta en azul, en un tiempo X de ejecucion ejecutamos una consulta a un webservice el cual se ejecuta en un nuevo hilo, que colocamos en color rojo, el cual se quedara corriendo por tiempo indefinido consumiendo constantemente ese webservice, y un tercer  hilo de colro verde de impresion de un documento o reporte, y el hilo es cerrado una vez que concluye la impresion.


Para realizar la implementación de un hilo en android, hay seguir los siguientes pasos muy básicos:
  1.     Extender la clase Thread.
  2.     Implementar el médoto run().
  3.     Para actualizar la interfaz de usuario, utilizar el método runOnUiThread().
A continuación para probar este proceso, agregamos un botón a nuestra actividad, colocamos el siguiente código sencillo que explica el proceso anterior:

Este codigo hace que la aplicación queda bloqueada por unos 10 segundos al hacer clic, y no permite realizar otra tarea.

Haciendo un cambios al ejemplo anterior, se agrega un Progressbar debajo:
Y corregimos el codigo a:
La aplicación llama al subproceso a través del clic al botón, que se ejecuta en un subproceso secundario, y no afecta el hilo principal.