Red de conocimiento informático - Material del sitio web - Cómo utilizar JNI en Android

Cómo utilizar JNI en Android

1. Introducción

Sabemos que la biblioteca subyacente del sistema Android está escrita en c/c y la aplicación de Android de capa superior llama a la interfaz subyacente a través de la máquina virtual Java. para conectar la biblioteca c/c subyacente y la interfaz entre aplicaciones Java es JNI (JavaNative Interface). Este artículo describe cómo configurar el entorno de desarrollo AndroidJNI en ubuntu y cómo escribir una biblioteca de funciones C simple y una interfaz JNI, llamar a estas interfaces escribiendo un programa Java y finalmente ejecutarlo en el emulador.

2. Configuración del entorno

2.1. Instalar jdk1.6

(1) Descargue el archivo jdk-6u29-linux-i586.bin del jdk oficial. sitio web.

(2) Ejecutar archivo de instalación jdk

[html] ¿ver Plaincopyprint?

01.$chmod a x jdk-6u29-linux-i586.bin p>

02.$jdk-6u29-linux-i586.bin

$chmod a x jdk-6u29-linux-i586.bin

$jdk-6u29- linux- i586.bin

(3) Configurar variables de entorno jdk

[html] ¿ver Plaincopyprint?

01.$sudo vim /etc/profile

02.#JAVAEVIRENMENT

03.exportJAVA_HOME=/usr/lib/java/jdk1.6.0_29

04.exportJRE_HOME=$JAVA_HOME/jre

05.?exportCLASSPATH=$JAVA_HOME/lib?:$JRE_HOME/lib:$CLASSPATH

06.exportPATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH

$ sudo vim /etc/profile

#JAVAEVIRENMENT

exportJAVA_HOME=/usr/lib/java/jdk1.6.0_29

exportJRE_HOME=$JAVA_HOME/jre

p>

exportCLASSPATH=$JAVA_HOME/lib?:$JRE_HOME/lib:$CLASSPATH

exportPATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH

Después de guardar Salga de la edición y reinicie el sistema.

(4) Verificar instalación

[html] ¿ver Plaincopyprint?

01.$java -version

02.javaversion "1.6 .0_29"

03.Java(TM)SE Runtime Environment (compilación 1.6.0_29-b11)

04.JavaHotSpot(TM) Server VM (compilación 20.4-b02, modo mixto) )

05.$javah

06. Uso: javah[opción]lt; clase gt;

07. >

08.-help genera este mensaje de ayuda y sale

09.-classpathlt; la ruta utilizada para cargar la clase

10.-bootclasspathlt; ;La ruta utilizada para cargar la clase de arranque

11.-dlt; Directorio gt; Directorio de salida

12.-olt Archivo de salida (solo -d o -o; )

13.-jni genera archivos de encabezado estilo JNI (predeterminado)

14.-version genera información de la versión

15.- verbose habilita la salida detallada

16. -force siempre escribe en el archivo de salida

17. Utilice el nombre completo para especificar (ejemplo

18. Por ejemplo, java. .lang.Objeto).

$java -version

javaversion "1.6.0_29"

Java(TM)SE Runtime Environment (compilación 1.6.0_29-b11)

VM de servidor JavaHotSpot(TM) (compilación 20.4-b02, modo mixto)

$javah

Uso: javah[opción]lt clase gt;

Las [opciones] incluyen:

-ayuda a generar este mensaje de ayuda y salir

-classpathlt gt; -bootclasspathlt; ruta gt; ruta utilizada para cargar las clases de arranque

-dlt; directorio de salida

-olt archivo de salida (solo se puede usar -d o uno de -o)

-jni genera archivos de encabezado estilo JNI (predeterminado)

-version genera información de la versión

-verbose habilita la salida detallada

-force siempre escribe en el archivo de salida

Especifique la utilizando el nombre completo (por ejemplo,

por ejemplo, java.lang.Object). 2.2. Instalar el entorno de desarrollo de aplicaciones de Android

La instalación del entorno de desarrollo de aplicaciones de Android en Ubuntu es similar a Windows. Simplemente instale el siguiente software en orden:

(1) Eclipse

(2) ADT

(3) AndroidSDK

La única diferencia con la instalación en Windows es que al descargar este software, debe descargar el paquete de instalación de la versión de Linux. .

Después de instalar el entorno de desarrollo anterior para la aplicación de Android, también puede elegir si desea configurar las variables de entorno del emulador y las herramientas adb para facilitar el uso durante el desarrollo de JNI.

Los pasos de configuración son los siguientes:

Agregue el directorio donde se encuentra el emulador android-sdk-linux/tools y el directorio donde se encuentra adb android-sdk-linux/platform-tools a las variables de entorno. android-sdk-linux se refiere al paquete de instalación de androidsdk. El directorio de descompresión de android-sdk_rxx-linux.

¿[plain] ver Plaincopyprint?

01.$sudo vim /etc/profile

02.exportPATH=~/software/android/android-sdk- linux/tools:$PATH

03. exportPATH=~/software/android/android-sdk-linux/platform-tools:$PATH

$sudo vim /etc/profile

exportPATH=~/software/android/android-sdk-linux/tools:$PATH

exportPATH=~/software/android/android-sdk-linux/platform-tools:$ RUTA

Salga después de editar y reinicie para que surta efecto.

2.3. Instalar NDK

NDK es una herramienta proporcionada por Android para compilar código nativo de Android.

(1) Descargue ndk desde el sitio web oficial de androidndk/sdk/ndk/index.html. La última versión es android-ndk-r6b-linux-x86.tar.bz2.

( 2) Descomprima ndk en el directorio de trabajo:

[plain] ¿ver Plaincopyprint?

01.$tar -xvf android-ndk-r6b-linux-x86.tar.bz2

02.$sudo mv android-ndk-r6b /usr/local/ndk

$tar -xvf android-ndk-r6b-linux-x86.tar.bz2

$sudo mv android-ndk-r6b /usr/local/ndk

(3) Establecer variables de entorno ndk

[plain] ¿ver Plaincopyprint?

01 .$sudo vim /etc/profile

02.exportPATH=/usr/local/ndk:$PATH

$sudo vim /etc/profile

exportPATH =/usr/local/ndk:$PATH

Después de editar, guarde y salga, y reinicie para que surta efecto

(4) Verifique la instalación

[plain] ver Plaincopyprint ?

01.$ cd/usr/local/ndk/samples/hello-jni/

02.$ ndk-build

03.Gdbserver: [ arm-linux-androideabi-4.4.3] libs/armeabi/gdbserver

04.Gdbsetup: libs/armeabi/gdb.setup

05.Instalar: libhello-jni.so = gt; libs/armeabi/libhello-jni.so

$ cd/usr/local/ndk/samples/hello-jni/

$ ndk-build

Gdbserver: [arm-linux-androideabi-4.4.3] libs/armeabi/gdbserver

Gdbsetup: libs/armeabi/gdb.setup

Instalar: libhello-jni.so = gt; libs/armeabi/libhello-jni.so

Implementación 3.JNI

Necesitamos definir una interfaz c/c que se ajuste a la especificación de la interfaz JNI. Esta interfaz no necesita ser demasiado complicada, por ejemplo, generar una cadena. A continuación, debe compilar el archivo de código de la interfaz c/c en un archivo .so de biblioteca compartida (biblioteca dinámica) y colocarlo en el directorio correspondiente del simulador. Finalmente, inicie la aplicación Java y podrá ver el efecto final.

3.1. Escribir código de aplicación Java

(1) Inicie Eclipse y cree un nuevo proyecto de Android

Proyecto: JNITest

Paquete: org .tonny.jni

Actividad: JNITest

(2) Editar archivo de recursos

Edite el archivo res/values/strings.xml de la siguiente manera:

Edite el archivo res/layout/main.xml

Agregamos un control EditText y un control Button a la interfaz principal.

(3) Editar el archivo JNITest.java

estático significa que cuando el sistema carga la clase por primera vez, este código se ejecutará primero , que se expresa aquí Cargue el archivo de biblioteca dinámica libJNITest.so.

Mira este párrafo nuevamente:

[java] ¿ver Plaincopyprint?

01.privatenativeString GetReply();

privatenativeString GetReply( );

nativo significa que este método está definido por código local y necesita llamar al código c/c local a través de la interfaz jni.

[java] ver Plaincopyprint?

01.publicvoidonClick(Ver arg0) {

02.edtName.setText(respuesta);

03.}

publicvoidonClick(View arg0) {

edtName.setText(respuesta);

}

Este código significa Después Al hacer clic en el botón, se muestra la cadena devuelta por el método nativo al control EditText.

(4) Compile el proyecto y genere el archivo .class.

3.2 Utilice la herramienta javah para generar un archivo de encabezado en lenguaje C que cumpla con la especificación JNI

En la terminal, ingrese el directorio bin donde se encuentra el proyecto de Android

¿[plain] ver Plaincopyprint?

01.$cd ~/project/Android/JNITest/bin

$cd ~/project/Android/JNITest/bin

Usamos ls Si ejecuta el comando, puede ver que hay un directorio de clases debajo del directorio bin, y su estructura de directorio es clases/org/tonny/jni, es decir, la estructura de subdirectorio de clases es el nombre del paquete del proyecto de Android org.tonny.jni. Tenga en cuenta que cuando nos preparamos para ejecutar el siguiente comando javah, debemos ingresar al directorio de nivel superior org/tonny/jni, es decir, el directorio de clases; de lo contrario, javah le indicará que no se puede encontrar la clase java relevante.

Continuar a continuación:

[plain] ver Plaincopyprint?

01.$cd clases

02.$javah org.tonny. jni.JNITest

03.$ls

04.org org_tonny_jni_JNITest.h

$cd clases

$javah org.tonny. jni.JNITest

$ls

org org_tonny_jni_JNITest.h

Ejecute el comando javahorg.tonny.jni.JNITest, el encabezado org_tonny_jni_JNITest.h se generará en el documento del directorio de clases. Si no ingresa al directorio de clases, también puede hacer esto:

[plain] ver Plaincopyprint?

01.$javah -classpath ~/project/Android/JNITest/bin /classesorg .tonny.jni.JNITest

$javah -classpath ~/project/Android/JNITest/bin/classesorg.tonny.jni.JNITest

El parámetro -classpath indica el directorio donde se carga la clase.

3.3. Escribir código c/c

Después de generar el archivo de encabezado org_tonny_jni_JNITest.h, podemos escribir el código de función correspondiente.

A continuación, cree un nuevo directorio jni en el directorio del proyecto de Android, es decir, ~/project/Android/JNITest/jni. Copie el archivo de encabezado org_tonny_jni_JNITest.h en el directorio jni y cree un nuevo archivo org_tonny_jni_JNITest.c en el directorio jni. El código de edición es el siguiente:

[cpp] ver Plaincopyprint?

01.#includelt;jni.hgt;

02.#includelt;string. .hgt;

03.#include"org_tonny_jni_JNITest.h"

04.

05.

06.JNIEXPORTjstring JNICALLJava_org_tonny_jni_JNITest_GetReply

07.(JNIEnv * env, jobject obj){

08.return(*env)-gt; NewStringUTF(env, (char*)"Hola, JNITest");

09.}

#includelt;jni.hgt;

#includelt;string.hgt;

#include"org_tonny_jni_JNITest.h"

JNIEXPORTjstring JNICALLJava_org_tonny_jni_JNITest_GetReply

(JNIEnv *env, jobject obj){

return(*env)-gt NewStringUTF(env, (char*)"Hola , JNITest");

}

Podemos ver que la implementación de esta función es bastante sencilla, devolviendo una cadena: "Hola, JNITest"

3.4 Escribir el archivo Android.mk

Cree un nuevo archivo Android.mk en el directorio ~/project/Android/JNITest/jni. Android puede compilar el módulo de acuerdo con los parámetros de compilación de este archivo.

Edite el archivo Android.mk de la siguiente manera:

[plain] ver Plaincopyprint?

01.LOCAL_PATH:= $(call my-dir)

02. include$ (CLEAR_VARS)

03.LOCAL_MODULE:= libJNITest

04.LOCAL_SRC_FILES:= org_tonny_jni_JNITest.c

05.include$(BUILD_SHARED_LIBRARY)

LOCAL_PATH:= $(llamar a mi-dir)

incluir$(CLEAR_VARS)

LOCAL_MODULE:= libJNITest

LOCAL_SRC_FILES:= org_tonny_jni_JNITest.c

include$(BUILD_SHARED_LIBRARY)

LOCAL_MODULE representa el nombre de la biblioteca dinámica compilada

LOCAL_SRC_FILES representa el archivo de código fuente

3.5. Utilice la herramienta ndk para compilar y generar el archivo .so

Vaya al directorio del proyecto JNITest y ejecute el comando ndk-build para generar el archivo libJNITest.so.

¿[plain] ver Plaincopyprint?

01.$cd ~/project/Android/JNITest/

02.$ndk-build

03.Nombre de atributo inválido:

04.paquete

05.Instalación: libJNITest.so =gt; libs/armeabi/libJNITest.so

$cd ~/project/Android/JNITest/

$ndk-build

Nombre de atributo no válido:

paquete

Instalación: libJNITest.so = gt; libs/armeabi/libJNITest.so

Puedes ver que el archivo libJNITest.so se genera en el directorio libs/armeabi del directorio del proyecto.

3.6. Ejecutar en el emulador

(1) Primero, iniciamos el emulador de Android.

Ingrese al directorio donde se encuentra el emulador y ejecute el comando del emulador:

[plain] view Plaincopyprint?

01.$cd ~/software/android/android-sdk-linux/ herramientas

02.$./emulator @AVD-2.3.3-V10 -partition-size 512

$cd ~/software/android/android-sdk-linux/tools

$./emulator @AVD-2.3.3-V10 -partition-size 512

AVD-2.3.3-V10 representa el nombre de su emulador, que es el mismo que el AVDName en Eclipse-gt; AVDManager En consecuencia, -partition-size indica la capacidad del dispositivo de almacenamiento del simulador.

(2) A continuación, debemos copiar el archivo libJNITest.so al directorio /system/lib del simulador y ejecutar el siguiente comando:

[plain] view Plaincopyprint?

01.$cd ~/project/Android/JNITest/libs/armeabi/

02.$adb remount

03.$adb push libJNITest.so / system/lib

04,80 KB/s (10084 bytes en 0,121 s)

$cd ~/project/Android/JNITest/libs/armeabi/

$ adb remount

$adb push libJNITest.so /system/lib

80 KB/s (10084 bytes en 0,121 s)

Cuando se ve en el terminal Cuando hay información como una velocidad de transmisión de 80 KB/s (10084 bytes en 0,121 s), la copia se realiza correctamente.

(3) Ejecute el programa JNITest en la terminal. Podemos hacer esto en Eclipse, hacer clic derecho en el proyecto JNITest, RunAs-gt e iniciar el programa en el emulador.