introducción android ndk
DESCRIPTION
Introducción al android ndk durante el Barcelona gtugTRANSCRIPT
Introducción
¿Qué es? ¿Qué permite? Librerías incluidas ¿Cuándo usarlo?
¿Qué es?
Conjunto de herramientas para compilar componentes nativos y poder utilizarlos
en aplicaciones Android.
¿Qué es?
¡¡¿¿What??!!
¿Qué permite?
Entre otras cosas permite Utilizar librerías C/C++ Invocar código C/C++ desde Java (y al revés) OpenGL ES 1.0 y 2.0
Desde NDKr5 (Gingerbread) Aplicación android escrita completamente en C/C++
(activities nativas) Acceder input (teclado, touch screen) Acceder sensores (acelerómetro, brújula...) Reproducir audio Recuperar recursos incluidos en el APK (R.*)
Librerías incluidas
JNI interface headers libc (C library) headers libm (math library)
headers libz (Zlib compression)
headers liblog (Android logging)
header OpenGL ES 1.1 and
OpenGL ES 2.0 (3D graphics libraries) headers
libjnigraphics (Pixel buffer access) header (for Android 2.2 and above).
A Minimal set of headers for C++ support
OpenSL ES native audio libraries
Android native application APIS
¿Cuándo usarlo?
No recomendado para la mayoría de las aplicaciones
No siempre aumenta el rendimiento pero siempe incrementa la complejidad
Sospechosos habituales
Operaciones de CPU intensivas, que no reserven mucha memoria: procesamiento de señales, simulaciones
físicas, juegos...
Primeros Pasos
Requisitos Instalación Ejemplos
Requisitos
Android SDK Android 1.5 SDK o superior
Sistemas operativos soportados Windows XP (32-bit) o Vista (32- or 64-bit). Mac OS X 10.4.8 o superior (x86 only). Linux (32 o 64-bit).
Herramienta de desarrollo requeridas GNU Make 3.81 o superior. Versión reciente de awk. Para Windows, Cygwin 1.7 o superior.
Instalación
Descargar e instalar Android SDK
http://developer.android.com/sdk/index.html
Descargar y descomprimir Android NDK
http://developer.android.com/sdk/ndk/index.html
Incluir directorio NDK en el PATH
export NDK_ROOT=/home/fegabe/android-ndk-r5
export PATH=$PATH:$NDK_ROOT
Ejemplos incluidos con NDK
hello-jni two-libs san-angeles hello-gl2
hello-neon bitmap-plasma native-activity native-plasma
La mejor manera de aprender NDK y saber qué se puede hacer
Calculadora NDK
Código Java Código C Android.mk Compilar y ejecutar
Código Java. Calculator.javaCalculadora NDK
package org.gtug.bcn.fegabe.ndk.calculator;
// Cargamos la librería 'sample-calculator' durante// el arranque de la aplicación. static { System.loadLibrary("sample-calculator");}
// Método nativo que se implementa en la librería// nativa 'sample-calculator', se empaqueta junto a esta// aplicación.Private static native int operate(int value1, int value2, String operation);
public static int performOperation(int value1, int value2, String operation) { // Se invoca el método nativo como si fuera un método // normal return operate(value1, value2, operation);}
Código C. calculator.cCalculadora NDK
// El nombre del método en el código nativo se // forma concatenando el package donde está definido // (org.gtug.bcn.fegabe.ndk.calculator), el nombre de la // clase (Calculator) y el nombre del método (operate)jint Java_org_gtug_bcn_fegabe_ndk_calculator_Calculator_operate(JNIEnv *env,jclass clazz, jint value1, jint value2, jstring operation) {
int result = 0; const char* strOperation; strOperation = (*env)->GetStringUTFChars(env, operation, 0);
if (strcmp(strOperation, "+") == 0) result = value1 + value2; LOGI("Calculator_operate: %d %s %d = %d", value1,
strOperation, value2, result); return result;}
Android.mk 1/2Calculadora NDK
Se trata de un Makefile que describe al compilador de NDK los ficheros C/C++.
Crear estos makefiles es una de las partes más complicadas de NDK, por ello conviene echar una vistazo a los ejemplos que vienen para ver otros Android.mk que incluyen comentarios.
Android.mk 2/2Calculadora NDK
# Android.mk debe comenzar con la variable LOCAL_PATH que localiza los fuentes en el árbol de directorios. En este caso, la macro 'my-dir' devuelve el path del directorio actual.LOCAL_PATH := $(call my-dir)
# CLEAR_VARS limpia las variables LOCAL_XXX (LOCAL_MODULE, LOCAL_SRC_FILES...) excepto LOCAL_PATH.include $(CLEAR_VARS)
# LOCAL_MODULE debe ser definida para identificar cada módulo descrito en el Android.mk. El nombre debe ser único y no contener espacios. La librería dinámica recibirá el nombre del módulo, en este caso se generará el fichero 'libsample-calculator.so'.LOCAL_MODULE := sample-calculator
# LOCAL_SRC_FILES contiene la lista de ficheros C y/o C++.LOCAL_SRC_FILES := calculator.c
# Lista de flags de linkado usados durante la compilación.LOCAL_LDLIBS := -llog
# BUILD_SHARED_LIBRARY indica que el módulo ha acabado indicando qué compilar. Existe también la variable BUILD_STATIC_LIBRARY para generar una librería estática.include $(BUILD_SHARED_LIBRARY)
Compilar y ejecutarCalculadora NDK
$ <directorio-proyecto-ndk>/ndk-build
Se genera la librería 'libsample-calculator.so' en la carpeta 'libs'
Finalmente compilamos el proyecto en Eclipse para generar el .APK y ya podemos ejecutarlo en el emulador o dispositivo.
What else?
JNI Types Recibir/enviar Strings
Cómo generar headers Invocar Java desde nativo Proyectos NDK Crystax, librerías comunes C/C++
JNI TypesWhat else?
Primitive Types Reference Types
Ejemplo
jint Java_org_gtug_bcn_fegabe_ndk_calculator_Calculator_operate(JNIEnv *env,jclass clazz, jint value1, jint value2, jstring operation)
Recibir/enviar StringsWhat else?
jstring to C/C++ strings
GetStringUTFChars
ReleaseStringUTFChars
construct new String
NewStringUTF
Demo Whatelse
Con otras referencias como Arrays sucede similar
Generar HeadersWhat else?
Utilizando javah podemos generar automáticamente los headers en código C
/bin$ javah -jni org.gtug.bcn.fegabe.ndk.calculator
.WhatelseActivity
Invocar Java desde nativoWhat else?
Función nativa que invoca método Java
Método Java
JNIEXPORT void JNICALLJava_Callbacks_nativeMethod(JNIEnv *env, jobject obj, jint depth) {
jclass cls = (*env)->GetObjectClass(env, obj); jmethodID method =(*env)->GetMethodID(env, cls, "callback", "(I)V"); if (method == 0) return; (*env)->CallVoidMethod(env, obj, method, depth);}
private void callback(int depth) { … }
Proyectos que usan NDKWhat else?
Quakecode.google.com/p/glesquake
Quake 2code.google.com/p/quake2android
Quake 3code.google.com/p/kwaak3
Doomcode.google.com/p/doom-for-android
Box2D, librería físicas 2Dcode.google.com/p/akjava-android-project
ARToolkit, librería realidad aumentadacode.google.com/p/andar
CrystaX NDKWhat else?
Android NDK personalizado con soporte para excepciones C++, RTTI y STL
Muy útil para compilar librerías ya existentes con NDK
http://www.crystax.net/android/ndk.php
Parsec. Ejemplo real NDK
Shoot'em old-school hecho por IdeaKnow para iPhone y Android gracias a NDK
Addictive gameplay
Cool vector graphics
20 amazing levels
GAME CENTER / OpenfeintOnline achievements & hiscores
Weapon upgrades
Bosses
Items
Allows to play your own music while in-game
parsec.ideaknow.com
Parsec. Experiencia
90 % código C común Cada plataforma implementa:
ciclo de vida, inicialización vista OpenGL, gamecenter/openfeint, gestión inputs, gestión audio
Lo más complicado: conseguir crear un Android.mk para compilarlo (un par de días)
¿Preguntas?