android-ndk - studio - android ndk64
¿Cómo resolver el java.lang.UnsatisfiedLinkError en NDK en Android? (12)
Aquí hay un tutorial de cómo usar el código nativo: here
Asegúrate de no tener espacios en la ruta de tu proyecto. Tampoco puedes usar un guión bajo en el nombre de tu paquete o proyecto.
Soy nuevo en el desarrollo de ndk en android. He pasado por el sistema de archivos de ndk android. Aquí, explicando lo que he hecho. 1) He creado una carpeta llamada "jni" y luego creo 2 archivos con el nombre de Android.mk y ndkfoo.c.
En Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# Here we give our module name and source file(s)
LOCAL_MODULE := ndkfoo
LOCAL_SRC_FILES := ndkfoo.c
include $(BUILD_SHARED_LIBRARY)
y en ndkfoo.c
#include <string.h>
#include <jni.h>
jstring Java_com_mindtherobot_samples_ndkfoo_NdkFooActivity_invokeNativeFunction(JNIEnv* env, jobject javaThis) {
return (*env)->NewStringUTF(env, "Hello from native code!");
}
entonces he creado la clase NdkFooActivity, en la que he escrito
// load the library - name matches jni/Android.mk
static {
System.loadLibrary("ndkfoo");
}
Pero ahora, cuando compilo desde cygwin en xp, crea un archivo .so con éxito y luego corro como una aplicación de Android. Me da java.lang.UnsatisfiedLinkError en LOGCAT.
Así que, por favor déjame saber dónde estoy equivocado.
Gracias por adelantado,
Aunque este no ha sido el problema del OP, tuve el mismo java.lang.UnsatisfiedLinkError debido a que faltaba
static {
System.loadLibrary("mylibraryname");
}
Cree un archivo Application.mk en la carpeta jni. Copie la siguiente línea y péguela en Application.mk y guarde. Ahora compile el proyecto con su cgywin y vuelva a ejecutar
APP_ABI: = armeabi armeabi-v7a
Creo que te olvidaste de cambiar el nombre del paquete.
Java_com_mindtherobot_samples_ndkfoo
Debe ser su paquete lo que ha especificado creando proyecto.
El nombre del método Java_com_mindtherobot_samples_ndkfoo_NdkFooActivity_invokeNativeFunction
puede no ser el mismo que el nombre de su paquete o nombre de clase. Para hacer este nombre del método exactamente igual debes usar javah
.
Esto creará un archivo de encabezado que tendrá el mismo nombre de método que se requiere. Para hacer que este archivo de encabezado vaya a la carpeta de clases en el contenedor de su proyecto (asegúrese de haber creado el archivo java con un método estático y genérelo correctamente) ) por este comando en tu terminal
~/workspace/Android_Example2/bin/classes$
En este directorio escribe el siguiente comando
sudo javah -jni com.NDK.android_example2.MainActivity
Cambie el nombre del paquete y el nombre de la clase de acuerdo con su proyecto. Esto creará un com_NDK_android_example2_MainActivity.h en su carpeta de clases.
Simplemente mueva este archivo a su carpeta jni
. En este archivo, habrá métodos estáticos que ha creado en el archivo MainActivity.java, pero simplemente se declaran no implementados que implementará en su archivo C
NOTA: Mientras Copia el método, verifique que los parámetros del método deban declararse, así que haga que declaren en su archivo C
Espero que esto ayude.
Estoy bastante seguro de que debería ser:
JNIEXPORT jstring JNICALL Java_com_mindtherobot_samples_ndkfoo_NdkFooActivity_invokeNativeFunction(JNIEnv* env, jobject javaThis) {
return (*env)->NewStringUTF(env, "Hello from native code!");
}
¿Qué SDK está apuntando y qué versión de NDK tiene? ¿El error que está recibiendo dice que no pudo cargar la biblioteca o que hubo un método no implementado? De cualquier manera, asegúrate de que no tienes un conjunto de android: hasCode = "false" en la etiqueta de la aplicación en tu manifiesto.
También puede abrir el archivo APK después de una compilación con winrar o algo similar para asegurarse de que el archivo libndkfoo.so se incluya realmente en el paquete.
De cualquier manera, si no declara la función nativa en NdkFooActivity obtendrá ese error, es decir
pública estática nativa String invocativoNativeFunction ();
Hay una buena probabilidad de que la firma sea incorrecta, como han mencionado otros.
Si ejecuta la utilidad javah, puede encontrar la firma exacta. Desde la carpeta bin de su proyecto, donde se genera .apk y se genera la raíz de la jerarquía de clases de Java, ejecute:
javah -o jni_sig.h com.mindtherobot.whatever.your.package.is.NdkFooActivity
... y, si tiene el nombre del paquete y la clase correctos, escribirá un encabezado (llamado jni_sig.h) con la (s) firma (s) de función correcta (s) para cualquier función nativa. Copie eso en su encabezado y archivo .c, agregando parámetros según sea necesario, y debería funcionar correctamente.
Reemplazar este
Java_com_mindtherobot_samples_ndkfoo_NdkFooActivity_invokeNativeFunction
Con
Java_your_packege_name_your_Activity_Name_invokeNativeFunction
Ejemplo si su paquete es com.pack y el nombre del nombre de la actividad es MainActivity entonces
Java_com_pack1_MainActivity_invokeNativeFunction
No te olvides de añadir referencia en la actividad.
// cargar la biblioteca - el nombre coincide con jni / Android.mk
static {
System.loadLibrary("ndkfoo");
}
public native String invokeNativeFunction();
Repita todos estos pasos que debería funcionar :)
Tal vez ya no sea relevante, pero por lo que sé, también debe agregar el prefijo "lib" a su nombre de biblioteca nativo. En su caso, necesita cambiar Android.mk a "LOCAL_MODULE: = libndkfoo" y mantener "System.loadLibrary (" ndkfoo ");" como están las cosas. Compruebe el código de ejemplo ndk.
También (solo encontré este problema), tenga en cuenta que System.loadLibrary () siempre generará una excepción si está realizando pruebas en el emulador Intel Atom x86. Funciona bien en emuladores de Android normales y depuración en un dispositivo físico.
También tuve un error java.lang.UnsatisfiedLinkError
. Verifiqué todo lo mencionado en las respuestas anteriores, pero seguía recibiendo el error. Eventualmente descubrí que los nombres de los métodos JNI no pueden tener guiones bajos.
Ejemplo: Java_com_example_app_NativeLib_print_out_stuff
<- genera java.lang.UnsatisfiedLinkError: print_out_stuff
Cambie el nombre de la función print_out_stuff a algo sin guiones bajos: Java_com_example_app_NativeLib_printOutStuff
<- works
JNIEXPORT jstring JNICALL Java_com_mindtherobot_samples_ndkfoo_NdkFooActivity_invokeNativeFunction(JNIEnv* env, jobject javaThis) {
return (*env)->NewStringUTF(env, "Hello from native code!");
}
el problema es que compilas para un procesador de destino y ejecutas en otro. Si compila en ARM (armeabi), ejecútelo en un emulador basado en armeabi. cree un archivo llamado application.mk en la misma carpeta que Android.mk y coloque en él uno de estos:
- APP_ABI: = x86
- APP_ABI: = armeabi
- APP_ABI: = mips
- APP_ABI: = armeabi x86 mips // para compilar en todos los destinos y obtendrás archivos 3 * .so
luego compilar-> ejecutar. deberia de funcionar.