Ejemplo: hello-jni

Este ejemplo te proporciona una guía para el uso de hello-jni, una aplicación mínima de C/C++ compilada con el NDK. El ejemplo está en el directorio hello-jni, en el repositorio ndk-samples, dentro de la rama android-mk.

Android.mk

Las siguientes dos líneas proporcionan el nombre del archivo de origen nativo, junto con el nombre de la biblioteca compartida que se compilará. El nombre completo de la biblioteca compilada es libhello-jni.so, luego de que el sistema de compilación agrega el prefijo lib y la extensión .so.

LOCAL_SRC_FILES := hello-jni.c
LOCAL_MODULE    := hello-jni

Consulta la página de Android.mk para obtener más información sobre lo que hace el archivo Android.mk y cómo usarlo.

Application.mk

Esta línea indica al sistema de compilación la CPU y la arquitectura para la compilación. En este ejemplo, el sistema de compilación compila para todas las arquitecturas admitidas.

APP_ABI := all

Consulta la página de Application.mk para obtener más información sobre el archivo Application.mk y cómo usarlo.

Implementación en Java

El archivo helloJNI.java se encuentra en hellojni/src/com/example/hellojni/. Llama a una función para obtener una string del lado nativo y, luego, la muestra en la pantalla.

El código fuente contiene tres líneas de particular interés para el usuario del NDK. Aquí se presentan en el orden en el que se usan, en lugar del orden de línea.

Esta llamada a función carga el archivo .so al iniciarse la aplicación.

Kotlin

System.loadLibrary("hello-jni")

Java

System.loadLibrary("hello-jni");

La palabra clave native en la declaración del método indica a la máquina virtual que la función está en la biblioteca compartida (es decir, que está implementada en el lado nativo).

Kotlin

external fun stringFromJNI(): String

Java

public native String stringFromJNI();

El framework de Android llama a la función cargada y declarada en los pasos anteriores, y muestra la string en la pantalla.

Kotlin

tv.text = stringFromJNI()

Java

tv.setText( stringFromJNI() );

Implementación en C

El archivo hello-jni.c se encuentra en hello-jni/jni/. Tiene una función que muestra una string que solicitó el lado Java. La declaración de la función es la siguiente:

JNIEXPORT jstring JNICALL
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
                                                  jobject thiz )

Esta declaración corresponde a la función nativa declarada en el código fuente de Java. El tipo de datos que se muestra, jstring, está definido en la Especificación de la interfaz nativa de Java. No es una string, sino un puntero a una string de Java.

El nombre de la función viene después de jstring, y se basa en el nombre de la función de Java y en la ruta de acceso al archivo que la contiene. Constrúyelo de acuerdo con las siguientes reglas:

  • Antepón Java_.
  • Describe la ruta de acceso al archivo relacionada con el directorio de origen de nivel superior.
  • Usa guiones bajos en lugar de barras diagonales.
  • Omite la extensión de archivo .java.
  • Después del último guión bajo, anexa el nombre de la función.

De acuerdo con esas reglas, el ejemplo usa el nombre de función Java_com_example_hellojni_HelloJni_stringFromJNI. El nombre hace referencia a una función de Java llamada stringFromJNI(), que se encuentra en hellojni/src/com/example/hellojni/HelloJni.java.

JNIEnv* es el puntero a la VM y jobject es un puntero al objeto this implícito que se pasa desde Java.

La siguiente línea llama a la API (*env) de la VM y le pasa un valor de retorno, es decir, la string que había solicitado la función de Java.

return (*env)->NewStringUTF(env, "Hello from JNI !
Compiled with ABI " ABI ".");