Archivo de la categoría: Programación

Android Virtual Device

Hola a todos,

compartiendo con todos ustedes más notas del curso de Android, en esta ocasión vamos a conocer el AVD; cómo usarlo para crear una máquina virtual de Android y depurar nuestras aplicaciones.

Aquí las notas: http://www.nachintoch.mx/teaching/mobile_dev/avd.pdf

Android Debug Bridge

Hola a todos,

continuando con el curso de Android, en esta ocasión les comparto unas notas sobre el ADB. Vamos a conocer esta herramienta y algunas de las instrucciones comunes que nos permiten interactuar con los dispositivos en los que probamos nuestras aplicaciones.

Sin más, aquí las notas: http://www.nachintoch.mx/teaching/mobile_dev/adb.pdf

Introducción a Android Studio (notas del curso de Android)

Hola a todos,

hoy les comparto una introducción a Android Studio. Vamos a conocer un poco de su historia, sus funciones principales y cómo nos ayuda a provechar el framework de Android.

El enlace a las notas: http://www.nachintoch.mx/teaching/mobile_dev/Android-Studio.pdf

Qué tomar en cuenta al desarrollar una aplicación para móviles (Notas del curso de Android)

Hola a todos,

aquí con otra entrega de las notas del curso de Android. En esta ocasión, vamos a continuar conociendo las capacidades y limitaciones de los dispositivos móviles en general; estas consideraciones no solo aplican a Android.

Las notas aquí: http://www.nachintoch.mx/teaching/mobile_dev/consideraciones-generales-dev-mob.pdf

Android como plataforma de desarrollo

Hola a todos,

Trayéndoles las siguientes notas del curso de Android, ahora vamos a conocer a Android como plataforma de desarrollo. Conoceremos las herramientas con las que podemos producir aplicaciones Android, cómo se administra la ejecución de las aplicaciones, cómo y qué se debe tomar en cuenta al desarrollar una aplicación.

Aquí las notas: http://www.nachintoch.mx/teaching/mobile_dev/android-framework.pdf

Android como Sistema Operativo

Hola a todos,

Continuando con el curso de Android, les comparto ahora un material que nos habla de las características de Android como sistema operativo. Un sistema operativo es un software bastante grande, que se encarga de administrar todos los recursos del sistema, atender las ordenes del usuario y mantener sus aplicaciones en ejecución.

¿qué mecanismos usa Android para realizar administrar la ejecución de un dispositivo móvil?

Aquí el enlace a las notas: http://www.nachintoch.mx/teaching/mobile_dev/android-OS.pdf

Introducción a Android (primeras notas del curso de Android)

Hola a todos,

Como comenté en el último post, estoy participando en un curso de Android y tengo el gusto de compartir con todos ustedes el material y las aplicaciones que desarrolle para el curso. Esto es algo que llevaba queriendo hacer hay ya un par de años; así que espero que encuentren el material de utilidad.

En esta primera publicación, les comparto unas notas que nos introducen a esta fantástica plataforma (si no lo habían notado ya, soy muy entusiasta de Android), nos cuenta sus orígenes y nos trae al presente para poder conocerla.

Más adelante, aplicaremos estos conceptos en aplicaciones; mientras conocemos el SDK y otras herramientas como Android Jetpack.

Enlace a las notas: http://www.nachintoch.mx/teaching/mobile_dev/introduccion.pdf

Debian: cómo ejecutar un programa o script al inicio del sistema

Hola a todos!

Para posts futuros, estoy trabajando en tutoriales para usar un equipo con Debian como un equipo de red (router + DNS); sin perder la funcionalidad de poderse usar como un sistema de propósito general. Para esto, podemos requerir de ejecutar una configuración que se inicia convenientemente cada vez que arranca el SO.

Hoy les comparto una forma en la que podemos iniciar un programa cualquiera durante el arranque de Debian. Debian define siete estados de ejecución (conocidos como RunLevel) que podemos usar como referencia para ejecutar un programa cuando el sistema cambia de estado. Estos estados son:

0. Apagado. El sistema está operando, pero ha comenzado el procedimiento de apagado (no reinicio).

  1. Un sólo usuario. Se usa principalmente para operaciones de mantenimiento. En este estado, no es posible utilizar todos los recursos del sistema y/o aplicaciones del usuario.

2 a 5. Multiusuario. La instalación por defecto de Debian no define diferencia alguna entre los estados 2, 3, 4 y 5; permitiéndole al usuario del sistema definir estos estados a su conveniencia.

6. Reinicio. El sistema estaba en un estado entre el 1 y el 5 y se está apagando para volver a iniciar instantáneamente. El estado 6 solo abarca la fase de apagado: cuando el sistema reinicia, pasa a estado 1. Esto es importante; ya que por ejemplo, en sistemas multiboot, al reiniciar el sistema el usuario puede elegir cargar un SO diferente.


Para ejecutar un programa durante el cambio de nivel de ejecución, empezamos por crear un archivo (cuyo nombre es indiferente) en el directorio /etc/init.d

Por ejemplo, el siguiente script se llama /etc/init.d/ejemplo.sh (sólo es una instrucción)

#! /bin/bash
### BEGIN INIT INFO
# Provides: Example loging
# Required-Start: $syslog
# Required-Stop: $syslog
# Default-Start: 1 2 3 4 5
# Default-Stop: 0 6
# Short-Description: Example
# Description: Created & tested by Nachintoch, contact@nachintoch.mx
#
### END INIT INFO
echo "Loging"
case "$1" in
 start)
 echo `date` >> /home/nachintoch/boot_log.txt
 ;;
 stop)
 echo `date` >> /home/nachintoch/shutdown.txt
 ;;
 *)
 echo "Uso: ejemplo.sh {start|stop}"
 exit 1
 ;;
esac
exit 0

Para asegurarnos que el script será ejecutado, cambiamos los permisos del mismo (puede que requieras permisos de super usaurio):

# chmod 755 /etc/init.d/ejemplo.sh

Ahora, este programa (script) no será ejecutado en ningún momento durante el ciclo de vida del sistema, a menos de que sea invocado manualmente… Necesitamos indicarle al sistema el o los niveles de ejecución en los que queremos que se ejecute.

Para ello, debemos crear un enlace simbólico hacia alguno de los descriptores de estados del sistema. Estos son siete sabios de Hyrule directorios que en principio contienen los scripts que se deben ejecutar cuando el sistema cambia a su nivel…. Digo en principio, porque las buenas prácticas prefieren contener los scripts en el directorio que acabamos de estudiar /etc/init.d, pues es posible que queramos ejecutar el mismo programa durante el arraque y el reinicio; por ejemplo.

Estos siete directorios con los scripts de arranque son:

  • /etc/rc0.d
  • /etc/rc1.d
  • /etc/rc2.d
  • /etc/rc3.d
  • /etc/rc4.d
  • /etc/rc5.d
  • /etc/rc6.d

El sistema usa los nombres de los enlaces simbólicos en los siete directorios mencionados, para distinguir arranques (1, 2, 3, 4, 5) de apagados (0 y 6)… Para simplificar las cosas, al crear el enlace simbólico, podemos usar el comando update-rc.d

# update-rc.d ejemplo.sh defaults

Si queremos evitar que los scripts sean invocados cuando cambie el estado del sistema, podemos eliminar los enlaces simbólicos de los directorios /etc/rcN.d o usar update-rc.d nuevamente:

# update-rc.d -f ejemplo.sh remove

Esto conserva el script original /etc/init.d/ejemplo.sh


Antes de terminar, necesito hacer una aclaración importante. Al terminar de explicar los siete niveles de ejecución de Debian, agregué un asterisco; porque si bien lo que dice ese párrafo es cierto, hay un detalle: no necesariamente la interfaz gráfica forma parte de los estados de ejecución. Esta es una diferencia importante que hacemos con sistemas basados en Debian y otros sistemas operativos como Gentoo o Windows, donde es posible definir el arranque del sistema como el inicio de la interfaz gráfica.

Dependiendo el entorno gráfico que utilices, puedes agregar scripts también para ejecutar durante su arranque. En mi caso, uso GTK+ porque Gnome3 es demasiado pesado para mi portatil de museo. Podemos ejecutar programas al inicio de sesión gráfica de un usuario para ejecutar programas que usan la interfaz gráfica. Yo hago esto para iniciar el salvapantalla, no porque me preocupe que una imagen se quede en el monitor para siempre (es LCD), pero porque dejar el escritorio y regresar para ver la matrix es bastante satisfactorio 🙂

Además, recordemos que los estados de ejecución del 2 al 5 son personalizables; por lo que podemos modificar las instrucciones de ejecución del inicio y del arranque del escritorio para definir uno de estos estados como “entorno gráfico”; pero esa será quizá historia de otro día.


Y bien, esto es lo que hacemos para dar de alta y baja potenciales servicios durante los cambios del ciclo de vida del sistema. Espero les sea de utilidad y que el límite sea la imaginación.

Android y Picasso: como resolver cargas infinitas (pérdida de objetivos-Target)

Hola a todos!

Si usas Picasso como una biblioteca tercera en tu aplicación Android, es posible que las descargas de imágenes hechas con Picasso parezcan nunca terminar.

Si activamos la caracterísitca de depuración de Picasso; como se muestra a continuación,

Picasso picasso = new Picasso.Builder(context).loggingEnabled(true).build();

al iniciar una carga con picasso, indicando algún objetivo

picasso.load("http://www.nachintoch.mx/images/shell_sort.gif").into(target);

es posible que veamos el siguiente mensaje en la consola de depuración (“Monitor Android”):

target got garbage collected

Esto significa que se ha ejecutado el recolector de basura y se ha llevado el target que le hayamos dado a Picasso al iniciar la carga. Al haber perdido el target, la imagen nunca se mostrará en el mismo y puede dejar nuestra aplicación en un estado inadecuado.


Esto ocurre debido a que Picasso mantiene referencias débiles a los target, por lo que son susceptibles a ser recolectados. Y aunque nuestra aplicación requiera un bajo consumo de recursos, siempre existe la posibilidad de que existan múltiples servicios en ejecución o alguna otra aplicación de alto consumo de recursos; como los juegos, y el SO al requerir liberar recursos, invoque el recolector de basura y ocurra este problema con los target.

Por lo anterior; considero una buena práctica aplicar siempre esta solución cuando se trabaje con Picasso para mitigar riesgos…


Si alguna vez has trabajado con referencias; por ejemplo, al implementar listas ligadas, probablemente tengas ya una idea de la solución, y es que es bastante simple.

Basta con mantener una referencia a nuestro target en el programa. No importa si declaramos una variable específica para los target, o si los almacenamos en un arreglo o en alguna estructura de datos; como una lista, un mapa o una cola concurrente.

Para hacer esto, podemos hacer lo siguiente. Puesto que Picasso requiere que los target implementen la interfaz com.squareup.picasso.Target podemos aprovechar los métodos que nos obliga a implementar en los target.

Para mantener una referencia a los target y evitar que sean recolectados, al iniciar la carga; hacemos la referencia al target:

Target target = someTarget;

Target[] targets = new Targets[]{someTarget};
LinkedList<Target> targets = new LinkedList<>();
targets.add(someTarget);
picasso.load("http://www.nachintoch.mx/images/rgb.jpg").into(someTarget);

Una vez que se haya realizado la carga, será invocado el método de Target onBitmapLoaded o onBitapFailed; dependiendo de si la carga fue exitosa o no. En ambos, incluimos el siguiente código para liberar los targets y con ellos el espacio en memoria: queremos que el recolector se lleve los targets después de que la carga haya concluido; no antes.

if(target == this) target = null;

int index = Arrays.asList(targets).indexOf(this);
if(index >= 0) targets[index] = null;

targets.remove(this);

Dependiendo de la estrategia que hayas usado para mantener una referencia “fuerte” al target y evitar la recolección de basura sino hasta este punto del programa; donde es esperado que ocurra.


Así que en pocas palabras, la solución a la recolección de los targets durante la carga con Picasso es mantener una referencia al target directamente.

Espero esto saque de algún apuro a alguien, yo perdí un día completo para descubrir esta solución y que el límite sea la imaginación.

Android Studio: Error “Unable to detect adb version…” al actualizar platform-tools o el IDE

Hola a todos!

Ya hemos resuelto algunos de los errores comunes que ocurren al usar Andorid Studio y el Android SDK en sus versiones más recientes en sistemas de 32 bits: es posible hacerlo sin tener que apuntar completamente a versiones previas, como hemos visto hasta ahora.

Esta semana vamos a resolver el problema de no ver nuestros dispositivos o emuladores para ejecutar una aplicación en desarrollo, o que el sistema no reconozca el ADB como un programa válido

unable-detect-adb


Esto se debe a que las nuevas versiones del ADB son programas de 64 bits y como ya he comentado en post anteriores, no es posible ejecutar estos programas en sistemas de 32 bits; por limitaciones físicas de los equipos…. Y no; instalar 2 veces el sistema operativo, no lo hace de 64 bits.

Puesto que no podemos ejecutar un programa de 64 bits por esta limitaciones, la solución es reemplazar el binario del ADB por uno de 32 bits. Podemos usar el que viene incluido con platform-tools v23.0.1, que podemos descargar a continuación:

https://dl-ssl.google.com/android/repository/platform-tools_r23.0.1-linux.zip

Descomprimimos el archivo y en el primer nivel jerárquico de directorios que contiene el ZIP, debe aparecer un archivo llamado “adb”

platform-tools

Copiamos el archivo “adb” y lo pegamos en

<android_sdk_home>/platform-tools

En este directorio ya exista un archivo llamado “adb”; debemos sobreescribirlo, pues al actualizar Android Studio o platform-tools se inserta la nueva versión de ADB; esa de 64 bits que nos da problemas, y debemos reemplazarla por esta versión de 32 bits para poderlo ejecutar.


Una vez que hayamos sobreescrito el archivo adb, Android Studio y el sistema deberían reconocer y ejecutar correctamente el ADB y deberíamos poder contactar nuestros dispositivos y emuladores Android.

correct-adb


-El límite es la imaginación-