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> 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 p>
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
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
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: p>
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 p>
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: p>
[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 p>
07.(JNIEnv * env, jobject obj){
08.return(*env)-gt; NewStringUTF(env, (char*)"Hola, JNITest"); p>
09.} p>
#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 p>
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.