En este caso va un post de introducción a la programación con Android (que es básicamente programación en Java), que es básicamente una adaptación de todos las entradas que he hecho en mi página personal recientemente. Android es un sistema operativo que tiene una acogida cada vez mayor y que, según mi opinión, es el futuro del desarrollo de aplicaciones para dispositivos móviles. Así que ahí va un nuevo aporte después de tanto tiempo...
Introducción a la programación con Android
Android es un estupendo sistema operativo para dispositivos móviles basado en Linux, y que nos proporciona un completo SDK para desarrollar nuestras propias aplicaciones de una manera rápida y divertida.
En esta sección aprenderemos a instalar/configurar el SDK y el plugin para Eclipse. Haremos el típico Hola Mundo, y explicaré un poco sobre la metodología de programación para esta plataforma. ¡Manos a la obra!
1. Instalar y configurar el SDK de android
Vamos a la página del Android SDK y descargamos la versión para nuestro sistema operativo. Yo uso Gentoo Linux, pero los pasos son prácticamente idénticos en Windows y en Mac. La última versión al escribir esta entrada es android-sdk_r06. Una vez que hayamos descargado el archivo, lo descomprimimos, entramos a la carpeta que se crea y ejecutamos (en Linux):
Código:
tools/android
En Windows:
Código:
SDK Setup.exe
Veremos algo como esto:
Hacemos clic en Available packages y desplegamos el árbol que aparece bajo Sites, Packages and Archives para instalar el API sobre la(s) que deseamos trabajar, y una vez la(s) hayamos seleccionado hacemos clic en Install Selected. En este caso he seleccionado el API 7 (para la versión 2.1 de Android), la documentación del API 7, los ejemplos del API 7 y el SDK del API 4 (para la versión 1.6 de Android). Es importante elegir las APIs adecuadas teniendo el cuenta el tipo de dispositivo para el que estamos desarrollando la aplicación. Escogí en este caso el API 4 puesto que el equipo sobre el que pruebo los programas (HTC Tattoo) viene con Android 1.6 (Donut) [más información sobre las versiones y sus codenames]. Por supuesto, si desarrollas con el API 4 tus programas tienen un 98% de probabilidades de correr sobre las versiones más recientes de Android sin modificación alguna.
Una vez haya terminado de descargar e instalar las APIs podemos crear un dispositivo virtual sobre el que probaremos nuestras aplicaciones. Hacemos clic en Virtual Devices al lado izquierdo, luego sobre el botón New… y configuramos el dispositivo:
Como puede apreciar en la imagen de arriba, debe poner un nombre al dispositivo, seleccionar el API sobre el que va a trabajar, darle un tamaño a la memoria ROM, escoger un tipo de pantalla y algunas configuraciones avanzadas que no se tratarán en este tutorial. Una vez tengamos esto, hacemos clic en Create AVD y si todo sale bien veremos algo como esto:
2. Instalar y configurar el plugin para Eclipse
Para este paso, necesitaremos Eclipse 3.5 (Galileo, recomendado) o 3.4. Abrimos eclipse, vamos a la Window -> Install New Software…
Hacemos clic en el botón Add… para añadir el repositorio de Android ( https://dl-ssl.google.com/android/eclipse/ ):
Clic en OK y ahora seleccionamos los plugins a instalar, y seguimos el proceso de instalación:
Una vez instalado, reiniciamos Eclipse y veremos que se han añadido algunos iconos extra en la barra de herramientas, y que además podemos crear proyectos para Android.
3. Hola Mundo en Android
Ahora vamos a crear un nuevo proyecto y aprender un poco más sobre cómo funcionan las aplicaciones para Android. Hacemos clic en el botón de creación de proyectos Android (o File… -> New Project -> Android Proyect):
Veremos el asistente de creación de proyectos para Android en donde debemos especificar: el nombre del proyecto (HolaParce), el API para el que vamos a desarrollar (1.6 en este caso), el nombre de la aplicación (Hola Parce en este caso), el nombre del paquete (se recomienda que sea un paquete nombrado con el estándar de Java, es decir, un dominio invertido), seleccionamos Create Activity y le damos un nombre (que cumpla las especificaciones de un nombre de clase en Java), y por último seleccionamos la versión mínima del API que deberán tener los dispositivos que corran nuestro aplicativo:
¡Clic en Finish y listo! Ahora podemos probar la aplicación… hacemos clic derecho sobre el Proyecto, seleccionamos Run as… -> Android Application. Se cargará el emulador y después de un par de minutos podremos ver nuestra aplicación:
4. Entendiendo el funcionamiento básico de las aplicaciones en Android
Las aplicaciones en Android funcionan bajo el esquema de “Actividades”. Una actividad presenta una interfaz gráfica (escrita en XML) que permite al usuario interactuar con la aplicación. Cada aplicación tiene varias actividades que se van mostrando al usuario según este las vaya necesitando. Una actividad llama a otra cuando sea necesario, y cada una de las actividades que se vayan mostrando se almacenan en una pila; es decir, cada vez que la aplicación lo requiera inserta una nueva actividad en la pila y, cuando esta ya no se necesite, se hace un push sobre esta lo cual deja en descubierto la actividad que estaba debajo. Importante leer esto para tener claro cada uno de los aspectos fundamentales de las aplicaciones Android.
Ahora, veremos detalladamente qué ocurrió en los pasos que seguimos arriba. Por ejemplo, al crear el proyecto se generan algunos archivos automáticamente. Veamos que hace cada uno de ellos…
Dentro del directorio res se han creado algunos subdirectorios:
- drawable-hdpi, drawable-mdpi, drawable-ldpi en donde se almacenan las imágenes que va a utilizar nuestra aplicación. La diferencia entre ellas es que debemos colocar las imágenes que aparecerán según el tipo de pantalla del dispositivo. En drawable-hdpi se colocarán las imágenes para dispositivos con alta resolución (High) y en drawable-ldpi (Low) pondremos las imágenes para dispositivos con pantallas pequeñas.
- values contiene inicialmente el archivo strings.xml, que es donde declaramos las cadenas de texto que usará nuestra aplicación. No es obligatorio definir todas las cadenas de texto allí, pero es bastante recomendable hacerlo. En este caso simplemente contiene la definición de una cadena de texto (llamada hello), que es la que se muestra al ejecutar la aplicación:
Código
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">Hello World, HolaParce!</string> <string name="app_name">Hola Parce</string> </resources>
- layout contiene los archivos XML que representan interfaces gráficas. Si echamos un vistazo al archivo generado (main.xml) veremos algo como esto:
Código
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> </LinearLayout>
- Los layouts son XML estrictos, así que deben comenzar con el encabezado <?xml version="1.0" encoding="utf-8"?> y todas las etiquetas abiertas deben ser debidamente cerradas.
- Los LinearLayout representan contenedores de widgets (algo similar al JPanel de swing en Java). Es decir, es la manera de organizar cada grupo de elementos de la interfaz gráfica.
- En este caso, dentro del contenedor solo tenemos un TextView (que sería algo así como un JLabel de swing en Java).
- Sea cual sea el elemento que pongamos en el layout, debemos especificar su anchura (android:layout_width) y altura (android:layout_height). Para cada parámetro podemos usar el valor fill_parent o wrap_content. fill_parent hará que el widget ocupe todo el tamaño posible, mientras que wrap_content hará que ocupe el menos posible.
- El parámetro android:text permite asignar un texto al TextView. En este caso se usa @string/hello que indica que se usará una variable llamada hello. Esta variable puede ser encontrada en el archivo strings.xml dentro del directorio values. También podríamos especificar el texto directamente, por ejemplo: android:text="Hola parcero!"
- Como tal vez se dio cuenta, es posible editar los archivos XML gráficamente o con el editor de textos de Eclipse.
Dentro del directorio gen se encuentra un archivo llamado R.java. Este archivo NO debemos modificarlo ya que es Eclipse quien se encarga de poner el código allí dentro. Este archivo sirve básicamente para enlazar las cosas que hagamos en XML con la programación en Java. Por ejemplo, se crea una referencia a la variable hello creada en el archivo strings.xml. Esto permite que podamos referenciar dicha variable desde Java (esto se explica con más detalle abajo).
Bajo el directorio src se creó un paquete y dentro de él un archivo en Java que es nuestra primera actividad (fíjese cómo la clase creada extiende la clase Activity del paquete android.app):
Código
package net.casidiablo.holaparce; import android.app.Activity; import android.os.Bundle; public class HolaParce extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } }
Veamos en detalle cada línea:
- Línea 1 define el nombre del paquete.
- Líneas 2 y 3 importamos las clases que necesitamos para correr la actividad.
- En la línea 4 podemos ver que la clase exitiende a Activity.
- En la línea 7 redefinimos el método onCreate de la clase Activity, el cual es ejecutado al momento de iniciar la aplicación. Note que no es necesario tener un método main; en Android se define una actividad principal que será ejecutada al iniciar la aplicación (más adelante veremos donde se configura esto).
- En la línea 9 se usa el método setContentView que define cual de las interfaces gráficas creadas en el directorio layout serán usadas. Como parámetro usamos la variable R.layout.main. Esto es algo confuso al principio así que lea atentamente: R, como vimos anteriormente, es una clase generada por Eclipse automáticamente cada vez que creamos nuevos componentes para la aplicación; dentro de ella se crean clases estáticas con variables enteras que representan cada uno de estos componentes (main.xml es entonces una variable entera llamada main, dentro de la clase estática layout, que a su vez se encuentra dentro de la clase R.java). Por ejemplo, para usar la variable hello desde Java, tendríamos que usar una referencia de tipo R.values.hello.
Por último, tenemos el archivo AndroidManifest.xml. Todas las aplicaciones deben tener este archivo y no debe ser renombrado. En él se especifican las opciones generales del programa, como el paquete principal, la actividad que deberá ejecutarse al iniciar la aplicación (y deben incluirse allí TODAS las actividades que se van usar), el icono a usar, los permisos, etc.
Código
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="net.casidiablo.holaparce" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".HolaParce" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <uses-sdk android:minSdkVersion="4" /> </manifest>
5. Operaciones avanzadas: acceder al dispositivo por consola y obtener una shell
Como sabemos, Android está basado en Linux, y como tal posee una interfaz de linea de comandos que podemos acceder usando las herramientas del sdk. Esto lo podemos hacer tanto para dispositivos virtuales, como el de este ejemplo, como para dispositivos reales. En este caso lo haremos con el dispositivo virtual que creamos para el ejemplo. Es tan sencillo como ejecutar esto en consola (en Linux):
Código:
tools/adb -s emulator5554 shell
Lo que hacemos con el comando anterior es indicarle al adb que queremos abrir una shell del dispositivo con serial emulator-5554. Para ver los dispositivos conectados actualmente y sus seriales usamos el comando adb devices. Si todo va bien veríamos algo como esto:
Código:
funtoo@larry tools % ./adb -s emulator-5554 shell
# ls
sqlite_stmt_journals
cache
sdcard
etc
system
sys
sbin
proc
init.rc
init.goldfish.rc
init
default.prop
data
root
dev
Desde dicha shell podemos hacer bastantes cosas, pero la más interesante para mi, es poder usar el SQLite3 para acceder a las bases de datos de las aplicaciones que creemos, lo cual nos permite una depuración mucho más rápida.
Depuración de aplicaciones en Android
Siguiendo con la serie de entradas sobre Android, aprenderemos a depurar de una manera sencilla las aplicaciones que escribamos. Muchas veces, al ejecutar la aplicación obtenemos un mensaje de este tipo:
Cuando estamos desarrollando aplicaciones normales en Java, usualmente imprimimos mensajes en consola que contienen la información de las excepciones que capturamos, y que nos permiten detectar los errores. En Android tendremos hacer uso de la clase Log, que genera logs (¡capitán obvio al rescate!).
Su uso es bastante simple. Como ejemplo usemos este programa que arrojaría un famoso NullPointerException:
Código
package net.casidiablo.ejemplo; import android.app.Activity; import android.os.Bundle; import android.util.Log; public class EjemploInvertir extends Activity { @Override public void onCreate(Bundle b) { super.onCreate(b); setContentView(R.layout.interfaz_grafica); try { x.length(); Log.d("Al inicio", "El error es: "+e.toString()); } } }
En este caso se usó el método d de la clase Log, el cual genera mensajes de tipo DEBUG. Existen otros como v, para VERBOSE, e para ERROR, etc. La lista completa la encuentras en el API de la clase.
Para leer el registro de errores desde Eclipse vamos a Window -> Show view -> Other… Dentro del cuadro de diálogo que se abre seleccionamos Android -> Logcat:
Espero que les sea de ayuda. No duden en comentar sus dudas o sugerencias.