Introducción Android NDK

Preview:

Citation preview

Introducción Android NDK

fernando@ideaknow.com@fegabe

Barcelona GTUGMarzo 2011

GTUG, Habemus Logo!

designed by Maria Orús Valls

maria.orus@gmail.com

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?

The End

¡Gracias!

fernando@ideaknow.com@fegabe

Recommended