Nota: Este tutorial ha sido donado a la comunidad de javaHispano por Intel. Intel espera que en el futuro sus procesadores incrementen considerablemente su presencia en los terminales móviles Android, por ello ha creído que este artículo sería interesante para nuestra comunidad.
Este artículo es una introducción a la creación de aplicaciones nativas Android* (desarrolladas mediante NDK, Native Development Kit) para dispositivos basados en arquitectura Intel® (AI). Discutiremos también la exportación de aplicaciones Android NDK que hayan sido creadas para dispositivos con otras arquitecturas a dispositivos basados en AI. Recorreremos dos escenarios, uno para mostrar el proceso de creación de una aplicación Android* básica mediante NDK de principio a fin y el otro para exhibir un proceso simple de exportación de una aplicación existente Android basada en NDK a ser utilizada en dispositivos basados en AI.
a. Creación de un proyecto Android predeterminado
b. Invocación de código nativo desde Java Sources
c. Utilización de javah para generar encabezados stub de JNI (Java Native Interface) para código nativo
d. Compilación de código nativo con NDK para AI
e. Recompilación, instalación y ejecución de la aplicación Android NDK para AI
Las aplicaciones Android pueden incorporar código nativo mediante el conjunto de herramientas Native Development Kit (NDK). Este permite a los desarrolladores reutilizar código heredado, programar hardware a bajo nivel o diferenciar sus aplicaciones aprovechando características de otro modo no óptimas ni posibles.
Este artículo es una introducción básica sobre cómo crear aplicaciones basadas en NDK para AI de principio a fin y sobre casos de uso sencillos para la exportación de aplicaciones existentes basadas en NDK a dispositivos con AI. Recorreremos paso a paso un escenario de desarrollo simple para demostrar el proceso.
Suponemos que ya tenemos instalado el entorno de desarrollo Android, inclusive Android SDK, Android NDK y tenemos configurado el emulador x86 para probar las aplicaciones. Consulte la sección Android Community del sitio Web de Intel para más información. Para que nuestro entorno de desarrollo sea sencillo, utilizaremos en mayor medida herramientas de la línea de comandos Linux*.
Supongamos que tenemos cierto código anterior que utiliza C y lenguaje ensamblador para el parsing de CPUID (consulte http://en.wikipedia.org/wiki/CPUID* para saber más de CPUID) A continuación se muestra el código C de nuestro ejemplo cpuid.c (solo como demostración)
Desearíamos llamar a cpuid_parse desde nuestra aplicación Android (Propósito de demostración solamente. La función cpuid_parse espera un búfer preasignado) y mostrar la salida dentro de la aplicación.
A continuación, una descripción paso a paso de la creación de una aplicación Android de principio a fin y la utilización del código nativo heredado anterior.
1. Creación de un proyecto Android predeterminado
Android SDFK cuenta con líneas de comando para generar un estructura de proyecto predeterminado para una típica aplicación “Hola Mundo”.Crearemos primero un proyecto predeterminado y luego modificaremos el código Java para agregar llamadas JNI y código nativo.
En la captura de pantalla anterior, hemos creado un directorio llamado labs/lab2 y utilizado la línea de comandos “android” para generar el proyecto predeterminado. Hemos especificado android-15 como el nivel API y denominado nuestra aplicación como “CPUIdApp” con el paquete com.example.cpuid.
Hemos utilizado la línea de comandos “ant” para generar el proyecto en modo debug e instalarlo mediante “adb” (o reinstalarlo si existe en el emulador o en el destino). Asumimos que ya ha tenido un emulador o un dispositivo asociado y es el único dispositivo listado en la salida del comando “adb devices”.
A continuación se ve una captura de pantalla del emulador Android x86 con ICS luego de completar el proceso anterior.
Al hacer clic en la aplicación, puede verse el mensaje predeterminado “Hello World” de la aplicación. Ahora modificaremos la aplicación para utilizar código nativo.
2. Invocación de código nativo desde Java sources
El proyecto Android predeterminado genera código Java para un típico proyecto “Hola Mundo” con espacio de nombres dado por el paquete (por ejemplo, com.example.cpuid). La captura de pantalla a continuación muestra el código fuente generado por el archivo Java principal.
Para utilizar código C/C++ en nuestro archivo de código Java, necesitamos primeramente declarar la llamada a JNI y cargar la biblioteca nativa como se ve destacado en amarillo en la captura de pantalla a continuación.
Como se ve en la declaración, la llamada nativa regresa un string de Java que podemos utilizar en cualquier sitio de nuestro código Java. Como se ve en la captura de pantalla anterior, modificamos TextView para mostrar el string que obtuvimos de nuestra llamada nativa. Ésta está destacada en rojo en el cuadro.
Éste es un caso muy simple de declaración y uso de llamadas nativas JNI en código fuente Java de una aplicación Android. A continuación, utilizaremos la herramienta “javah” para generar los stubs de encabezado JNI para código nativo y agregar o modificar código nativo para seguir los encabezados nativos JNI.
3. Utilización de “javah” para generar encabezados stub de JNI para código nativo
Ahora debemos modificar nuestro código nativo para cumplir con la especificación de la llamada de JNI. “javah” nos ayuda también a generar automáticamente los stub JNI de encabezamiento apropiados en base a los archivos fuente de Java. La herramienta “javah” requiere el archivo compilado de clase Java para generar los encabezados. Así utilizamos la herramienta "ant" para generar rápidamente archivos de clase Java como se muestra en la captura de pantalla a continuación ("ant debug").
Utilizar “javah” para generar el encabezado JNI como se muestra en la captura de pantalla (segundo destacado en amarillo). Éste creará un directorio “jni” y el stub encabezado basado en una clase Java. La captura de pantalla a continuación muestra el stub de encabezado JNI-nativo que se generó.
Crear archivo de código C correspondiente (“com_example_cpuid_CPUIdApp.c”) para el encabezado generado anteriormente. A continuación se muestra el código:
Llamamos al código nativo cpuid_parse y retorna el búfer parseado como string JNI. Estamos listos para compilar el código nativo utilizando el conjunto de herramientas x86 NDK.
4. Generación de código nativo con NDK para x86
Consulte la sección Android Community del sitio Web de Intel (/es-es/articles/ndk-for-ia) para más información sobre la instalación y uso de NDK para AI.
El conjunto de herramientas Android NDK utiliza un sistema de compilación que requiere un archivo make específico "Android.mk" presente en la carpeta del proyecto "jni" para compilar código nativo. Android.mk especifica todos los archivos de código C/C++ nativos a ser compilados, el encabezado y el tipo de compilación (por ejemplo: shared_library).
A continuación se muestra el código nativo del archivo make de Android para nuestro proyecto (“jni/Android.mk”)
Este es un escenario sencillo con archivos de código C y especificación de compilar una biblioteca compartida.
Podemos ahora emitir “ndk-build APP_ABI=x86” para compilar nuestro código nativo y generar la biblioteca compartida. El sistema de compilación de Android provee también otro archivo make suplementario “Application.mk” que podemos utilizar para especificar opciones de configuración adicionales.Por ejemplo, podemos especificar todos los ABI compatibles en el archivo Application.mk y la compilación NDK generará bibliotecas compartidas nativas para atender todas las arquitecturas.
La captura de pantalla anterior muestra la compilación exitosa de código nativo para x86 y una biblioteca compartida que está siendo generada e instalada. Estamos ahora preparados para recompilar nuestra aplicación Android e instalarla o ejecutarla en un emulador x86 o en el dispositivo final.
5. Recompilación, instalación y ejecución de la aplicación Android NDK para AI
Podemos utilizar “ant debug clean” para eliminar nuestros antiguos archivos compilados y aplicar “ant debug” nuevamente para comenzar una compilación completa del proyecto Android. Utilice “adb” para reinstalar la aplicación en el dispositivo final o el emulador x86 como se ve en la captura de pantalla a continuación.
La captura siguiente muestra el ícono de la aplicación dentro del emulador x86 y el resultado de la ejecución de la aplicación dentro del emulador x86.
Hemos compilado exitosamente la aplicación Android basada en NDK.
Las aplicaciones Android con código nativo tienen típicamente una estructura de proyecto estándar, con una carpeta “jni” que contiene el código nativo y los archivos de compilación correspondientes Android.mk/Application.mk. En la sección anterior, vimos un ejemplo sencillo de código nativo y el archivo Android.mk correspondiente.
Android NDK nos permite especificar todos los ABI de destino en Application.mk de una vez, y generar automáticamente bibliotecas compartidas nativas para todos los objetivos. El sistema de compilación Android empaquetará automáticamente todas las bibliotecas nativas necesarias dentro de APK y en tiempo de instalación el administrador de paquetes de Android instalará solamente la biblioteca nativa apropiada en base a la arquitectura finalmente usada.
Podemos invocar “ndk-build” o especificar Application.mk
APP_ABI := all OR APP_ABI := armeabi armeabi-v7a x86 |
Consulte http://developer.android.com/sdk/ndk/index.html para más información.
Para exportar una aplicación Android existente con código nativo, usualmente no destinada a x86, el proceso de modificación de la aplicación para hacerla compatible con AI es directo en la mayoría de los casos (como se discute anteriormente), a menos que la aplicación utilice lenguajes o algoritmos de ensamblador de arquitectura específica. Pueden haber otros problemas como la alineación de la memoria o usos de instrucciones específicos de la plataforma. Consulte /es-es/articles/ndk-android-application-porting-methodologies para más información.
Este artículo discute la creación y exportación de aplicaciones Android basadas en NDK para AI. Recorrimos paso a paso un proceso de creación de una aplicación basada en NDK a ser utilizada en AI, de inicio a fin. Discutimos también el proceso sencillo hecho posible por las herramientas NDK para exportar aplicaciones existentes Android basada en NDK a una AI.